我正在按照Javascript中创建getter和setter的教程,我有这样的代码:
// Create a new User object that accept an object of properties
function User(properties) {
// Iterate through the properties of the object, and make
// sure it's properly scoped
for (var i in properties) { (function(){
// Create a new getter for the property
this['get' + i] = function() {
return properties[i];
};
// Create a new setter for the property
this['set' + i] = function(val) {
properties[i] = val;
};
})(); }
}
// Create a new User object instance and pass in an object of
// properties to seed it with
var user = new User({
name: 'Bob',
age: 28
});
// Just note that the name property does not exist, as it's private
// within the property object
console.log(user.name == null);
// However, we are able to access its value using the new getname()
// method, that was dynamically generated
console.log(user.getname());
但是,控制台显示错误,说用户没有方法getname。代码试图动态生成getter和setter方法,对我来说看起来不错。有什么想法吗?
答案 0 :(得分:12)
其他答案是正确的,因为您需要将i
传递给您的匿名函数,但您也可以使用ES5 Getters and Setters执行此操作:
// Create a new User object that accept an object of properties
function User(properties) {
var self = this; // make sure we can access this inside our anon function
for (var i in properties) {
(function(i) {
Object.defineProperty(self, i, {
// Create a new getter for the property
get: function () {
return properties[i];
},
// Create a new setter for the property
set: function (val) {
properties[i] = val;
}
})
})(i);
}
}
使用ES5 getter和setter的好处是现在你可以这样做:
var user = new User({name: 'Bob'});
user.name; // Bob
user.name = 'Dan';
user.name; // Dan
由于它们是函数,它们会修改传入的properties
,而不仅仅是对象本身。您不必再使用getN
或setN
,只需使用.N
,这使得使用它看起来更像是访问对象的属性。
然而,这种方法并非普遍可移植(需要IE 9 +)。
这是我在实践中可能会做的事情:
function User(properties) {
Object.keys(properties).forEach(function (prop) {
Object.defineProperty(this, prop, {
// Create a new getter for the property
get: function () {
return properties[prop];
},
// Create a new setter for the property
set: function (val) {
properties[prop] = val;
}
})
}, this);
}
上面摆脱了你的for循环。你已经在使用匿名函数,所以不妨充分利用它。
答案 1 :(得分:2)
可能是关闭问题:
function User(properties) {
// Iterate through the properties of the object, and make
// sure it's properly scoped
for (var i in properties) {
(function(i){
// Create a new getter for the property
this['get' + i] = function() {
return properties[i];
};
// Create a new setter for the property
this['set' + i] = function(val) {
properties[i] = val;
};
}.call(this, i));
}
}
另外,正如@Paul所指出的那样,this
实际上是指for循环中包含的函数。不是User
功能。我通过使用调用并将User
指定给函数来修复它(不需要额外的变量)。
答案 2 :(得分:1)
您的循环功能正在丢失this
,执行var t = this
;外部循环并参考内部的t
。另外,将i
传递给您的函数。
function User(properties) {
var t = this, i;
for (i in properties) (function (i) {
t['get' + i] = function () { return properties[i]; };
t['set' + i] = function (val) { properties[i] = val; };
}(i));
}