在John Resig的书“Pro Javascript技术”中,他描述了一种使用以下代码生成动态对象方法的方法:
// Create a new user object that accepts an object of properties
function User(properties) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
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: 44
});
alert( user.getname() );
运行上面的代码会抛出此错误“user.getname不是函数”。
为实例化的每个对象生成动态函数的正确方法是什么?
答案 0 :(得分:11)
这本书的代码是?我有这本书,但我还没读完。
这本书中的错误。查看勘误表:http://www.apress.com/9781590597279
在匿名函数中,this
是全局window
。
您可以通过在其后添加.call(this, i)
来使其发挥作用。
function User(properties) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
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);
}
}
答案 1 :(得分:3)
内部自执行函数中的this
与外部User
函数中的window
不同。如您所见,它指的是全局this
。
如果您通过添加引用外部function User(properties) {
var self = this;
for (var i in properties) {
(function() {
self["get" + i] = function() { /* ... */ };
self["set" + i] = function() { /* ... */ };
})();
}
}
的变量稍微修改代码,问题就解决了。
function User(properties) {
for (var i in properties) {
this["get" + i] = function() { /* ... */ };
this["set" + i] = function() { /* ... */ };
}
}
那就是说,我不确定为什么这里甚至需要匿名的自动执行功能,所以你可以选择简单地将其完全删除,如下所示:
{{1}}
答案 2 :(得分:1)
以下是如何做到这一点。您需要将上下文保存到另一个变量中。另一个选择是不要执行你在for循环中执行的内部函数。
// Create a new user object that accepts an object of properties
function User( properties ) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
var that = this;
for ( var i in properties ) { (function(){
// Create a new getter for the property
that[ "get" + i ] = function() {
return properties[i];
};
// Create a new setter for the property
that[ "set" + i ] = function(val) {
properties[i] = val;
};
})(); }
}
选项2:
// Create a new user object that accepts an object of properties
function User( properties ) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
for ( var i in properties ) {
// 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;
};
}
}
答案 3 :(得分:1)
您可以使用this
方法为任何函数调用强制执行另一个apply
。
(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;
};
}).apply(this);