JS defineProperty和原型 [英] JS defineProperty and prototype
问题描述
如您所知,我们可以使用 defineProperty()
在JS中定义getter和setter。当我尝试使用 defineProperty()
来扩展我的课时,我一直被困住。
As you know we can define getters and setters in JS using defineProperty()
. I've been stuck when trying to extend my class using defineProperty()
.
这是一个示例代码:
我有一个必须添加到对象的字段数组
I have an array of fields which must be added to a object
fields = ["id", "name", "last_login"]
此外我还有将被修改的类
Also I have a class which will be modified
var User = (function(){
// constructor
function User(id, name){
this.id = id
this.name = name
}
return User;
})();
一个函数,它将使用 defineProperty()<为类添加字段/ code>
And a function which will add fields to the class using 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()
我有我的用户实例中的字段
define_fields(fields);
user1 = new User(1, "Thomas")
user2 = new User(2, "John")
但这些属性的值是相同的
But the values of these properties are identical
console.log(user2.id, user2.name) // 2, John
console.log(user1.id, user1.name) // 2, John
有没有办法让 defineProperty()
在这种情况下正常工作?
如果我理解问题是值
,对于每个类的实例,
变得相同,但我无法实现如何解决它。提前感谢
获取答案。
Is there any way to make defineProperty()
work properly in this case?
If I understand the problem is with value
which becomes identical for
each instance of the class but i can't realise how to fix it. Thanks in advance
for your answers.
UPD:
这样会抛出RangeError:超出最大调用堆栈大小
UPD: This way throws "RangeError: Maximum call stack size exceeded"
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
}
})
})
};
推荐答案
我得出了与Mikhail Kraynov 。每次调用构造函数时,该解决方案都会定义新属性。我想知道,如你所说,是否有一种方法可以将吸气剂和制定者放入原型中。这是我想出的:
I came to the same conclusion as Mikhail Kraynov three minutes after he answered. That solution defines new properties each time the constructor is called. I wondered if, as you asked, there was a way of putting the getters and setters in the prototype. Here is what I came up with:
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,但引用了一个(隐藏)属性每个保存字段值的实例。
In this solution I define the field getters and setters in the prototype but reference a (hidden) property in each instance which holds the field values.
请参阅此处的小提琴: http://jsfiddle.net/Ca7yq
See the fiddle here : http://jsfiddle.net/Ca7yq
我为小提琴添加了一些代码,以显示对枚举属性的一些影响: http://jsfiddle.net/Ca7yq/1/
I added some more code to the fiddle to show some effects on enumeration of properties : http://jsfiddle.net/Ca7yq/1/
这篇关于JS defineProperty和原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!