我已使用Object.defineProperty
使用getter定义了一个属性,我希望能够覆盖它而无需使用defineProperty
来防止对将要使用它的同事造成任何混淆但可能不知道这不是一个“正常”的财产。我尝试了writeable
和configurable
选项无济于事。
var fixture = {
name: 'foo',
color: 'green'
};
Object.defineProperty(fixture, 'email', {
get: function () {
return 'test+' + Date.now() + '@gmail.com';
},
configurable: true,
writeable: true
});
console.log(fixture.email); // test+<date>@gmail.com
fixture.email = 'bob'; // consumer attempts to overwrite
console.log(fixture.email); // test+<date>@gmail.com T_T
// this _will_ modify the property
Object.defineProperty(fixture, 'email', {
value: 'overwritten'
});
console.log(fixture.email);
答案 0 :(得分:3)
我尝试过可写和可配置的选项无济于事。
writable
仅适用于数据属性,即具有value
非getter和setter的数据属性。
configurable
仅允许删除和重新定义,而不是使属性可设置。
如果您希望fixture.email = 'bob';
不抛出错误,则必须在属性对象上提供set
方法。这个方法现在可以:
最后一个可能是最简单,最有价值的选择:
var fixture = {
name: 'foo',
color: 'green'
};
Object.defineProperty(fixture, 'email', {
get: function() {
return 'test+' + Date.now() + '@gmail.com';
},
set: function(val) {
Object.defineProperty(this, 'email', {
value: val,
writable: true
});
},
configurable: true,
enumerable: true
});
console.log(fixture.email); // test+<date>@gmail.com
fixture.email = 'bob'; // consumer attempts to overwrite
console.log(fixture.email); // bob
答案 1 :(得分:1)
虽然,我不会亲自使用它,但我猜你可以解决这个问题,只有当价值特定于你的期望时才设置它,如果它不是正确的值,抛出某种错误?
缺点当然是,一旦他们看到代码就像你那样放入代码,他们也可以这样做,但我想他们已经不那么混淆了;)我实际上更喜欢第二种选择我在底部显示,它只是提供了一个额外的setEmail方法来进行设置,或者通过更新&#34; DataContainer&#34;
内部的props.email属性。
var data = {
foo: 'foo',
bar: 'bar'
};
Object.defineProperty(data, 'email', {
get: function() {
if (typeof this._props === 'undefined') {
this._props = {};
}
return this._props.email;
},
set: function(val) {
if (!val || !val.private) {
throw 'no access exception';
}
if (this.email === val) {
return;
}
this._props.email = val.email;
},
configurable: false
});
console.log(data.email);
data.email = {
private: 1,
email: 'hey.you@somewhere.hi'
};
console.log(data.email);
try {
data.email = 'not allowed to set';
} finally {
console.log(data.email);
}
&#13;
另一种方法可能只是将逻辑构建到类构造函数中,并在函数上添加一个potentail setter(或在变量内部添加)
function DataContainer(options) {
var createProp = function(obj, propertyName, propertyHolder, isReadOnly) {
Object.defineProperty(obj, propertyName, {
get: function() {
return propertyHolder[propertyName];
},
set: function(val) {
if (isReadOnly) {
return;
}
propertyHolder[propertyName] = val;
},
configurable: false
});
if (isReadOnly) {
obj['set' + propertyName[0].toUpperCase() + propertyName.substr(1)] = function(val) {
//internal setter
propertyHolder[propertyName] = val;
};
}
},
prop = {},
fieldProp, fieldVal, ro;
if (options && options.fields) {
for (fieldProp in options.fields) {
if (options.fields.hasOwnProperty(fieldProp)) {
fieldVal = options.fields[fieldProp];
ro = false;
if (typeof fieldVal === 'object' && fieldVal.value) {
ro = fieldVal.readOnly || false;
prop[fieldProp] = fieldVal.value;
} else {
prop[fieldProp] = fieldVal;
}
createProp(this, fieldProp, prop, ro);
}
}
}
}
var data = new DataContainer({
fields: {
foo: 'foo',
bar: 'bar',
email: {
value: 'test@something.com',
readOnly: true
}
}
});
console.log(data);
data.email = 'test@test.com';
console.log(data.email);
data.setEmail('test@test.com');
console.log(data.email);
&#13;