pro JavaScript Techniques书中使用闭包实现属性getter、setter方法

书中,在User的函数的for循环中,通过闭包实现getter、setter方法,但我试了一下,程序运行时报错,
user.getname() 方法不存在。如果将闭包去除,user.getname()与user.getage()方法取得的值都是44,显然不对了,可就是不知道问题出在哪边。感觉这边通过使用闭包应该是可以实现getter、setter方法,但不知道为什么使用闭包后,总是提示getname等不是一个function。代码如下:
[code="java"]


<br> // the exaple in pro JavaScript Techniques</p> <pre><code> // 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&#39;s properly scoped (as discussed previously) for ( var i in properties ) { //(function(){ // Create a new getter for the property this[ &quot;get&quot; + i ] = function() { return properties[i]; }; // Create a new setter for the property this[ &quot;set&quot; + 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: &quot;Bob&quot;, age: 44 }); // Just note that the name property does not exist, as it&#39;s private // within the properties object alert( user.name == null ); // However, we&#39;re able to access its value using the new getname() // method, that was dynamically generated alert( &quot;name:&quot; + user.getname() + &quot;,age:&quot; + user.getage()); // Finally, we can see that it&#39;&#39;s possible to set and get the age using // the newly generated functions user.setage( 22 ); alert( user.getage() == 22 ); &lt;/script&gt; </code></pre> <p></head><br> <body><br> </body><br> </html><br> [/code]<br> 望解决,谢谢!</p>

原因是第二轮循环里,i变成了'age',所以properties[i]总是相当于properties['age']

正确的做法如下:
[code="javascript"]
for ( var j in properties ) {
var obj = this; //保存this,因为下面那个匿名function里面的this不同了
(function(i){
//如果用this,定义的getter和setter就不是user的了
obj[ "get" + i ] = function() {
return properties[i];
};

obj[ "set" + i ] = function(val) {
properties[i] = val;
};
})(j); //将j传入匿名函数中
}
[/code]

for循环有问题啦。你看清楚了哦。。

this[ "get" + i ] = function() {

return properties[i];

};

这里,你将getname方法也的值也设置成了44了。。第二轮循环的时候。

你可以在最后加一个

user.setname( 'bob' );

alert( user.getname() == 'bob' );

就知道了

用闭包的时候找不到成员是因为“this”用错了。在闭包内的“this”与闭包外的“this”并不总是指同一个对象的。

代码换成这样就明白了:
[code="js"]function User(props) {
var thisObj = this
for (var name in props) {
(function(n) {
thisObj['get' + n] = function() {
return props[n]
}
thisObj['set' + n] = function(val) {
props[n] = val
}
})(name)
}
}

var user = new User({ name: 'Bob', age: 44 })
alert('name: ' + user.getname() + ', age: ' + user.getage())[/code]