如您所知,我们可以使用defineProperty()在JS中定义getter和setter。在尝试使用defineProperty()扩展我的类时,我一直被困住了。
下面是一个示例代码:
我有一个必须添加到对象中的字段数组。
fields = ["id", "name", "last_login"]另外,我还有一个要修改的类。
var User = (function(){
// constructor
function User(id, name){
this.id = id
this.name = name
}
return User;
})();和一个函数,它将使用defineProperty()向类添加字段。
var define_fields = function (fields){
fields.forEach(function(field_name){
var value = null
Object.defineProperty(User.prototype, field_name, {
get: function(){ return value }
set: function(new_value){
/* some business logic goes here */
value = new_value
}
})
})
};在运行define_fields()之后,我在User的实例中有我的字段
define_fields(fields);
user1 = new User(1, "Thomas")
user2 = new User(2, "John")但是这些属性的值是相同的。
console.log(user2.id, user2.name) // 2, John
console.log(user1.id, user1.name) // 2, John在这种情况下,有什么方法可以使defineProperty()正常工作吗?如果我理解了value的问题,那么它对类的每个实例都是相同的,但我无法理解如何修复它。提前谢谢你的回答。
UPD:以这种方式抛出"RangeError:超过最大调用堆栈大小“
var define_fields = function (fields){
fields.forEach(function(field_name){
Object.defineProperty(User.prototype, field_name, {
get: function(){ return this[field_name] }
set: function(new_value){
/* some business logic goes here */
this[field_name] = new_value
}
})
})
};发布于 2014-10-03 14:48:26
请不要实现任何其他版本,因为它会占用您应用程序中的所有内存:
var Player = function(){this.__gold = 0};
Player.prototype = {
get gold(){
return this.__gold * 2;
},
set gold(gold){
this.__gold = gold;
},
};
var p = new Player();
p.gold = 2;
alert(p.gold); // 4如果实例化了10000个对象:
发布于 2012-12-27 11:18:04
三分钟后,我和Mikhail Kraynov得出了同样的结论。该解决方案在每次调用构造函数时都定义新属性。我想知道,正如您所问的,是否有一种将getter和setter放入原型的方法。以下是我想出的:
var User = (function () {
function User (id, nam) {
Object.defineProperty (this, '__', // Define property for field values
{ value: {} });
this.id = id;
this.nam = nam;
}
(function define_fields (fields){
fields.forEach (function (field_name) {
Object.defineProperty (User.prototype, field_name, {
get: function () { return this.__ [field_name]; },
set: function (new_value) {
// some business logic goes here
this.__[field_name] = new_value;
}
});
});
}) (fields);
return User;
}) (); 在此解决方案中,我在原型中定义字段getter和setter,但在每个实例中引用一个(隐藏)属性,该属性保存字段值。
看这里的小提琴:http://jsfiddle.net/Ca7yq
我在小提琴中添加了更多的代码,以显示对属性枚举的一些影响:http://jsfiddle.net/Ca7yq/1/
发布于 2012-12-27 09:40:21
在我看来,当defineProperties用于prototype时,所有实例都共享该属性。所以正确的变体可能是
var User = (function(){
// constructor
function User(id, name){
this.id = id
this.name = name
Object.defineProperty(this, "name", {
get: function(){ return name },
set: function(new_value){
//Some business logic, upperCase, for example
new_value = new_value.toUpperCase();
name = new_value
}
})
}
return User;
})();https://stackoverflow.com/questions/14047809
复制相似问题