javascript closure(闭包)的一个示例

今天一个同事看到John Resig 的Pro JavaScript Techniques这本书上的37页上有一段关于闭包的javascript代码,怎么调试都运行不正确,于是和他一起研究了一下,代码是这样的:

 
  1. // Create a new user object that accepts an object of properties    
  2. function User( properties ) {    
  3. // Iterate through the properties of the object, and make sure    
  4. // that it's properly scoped (as discussed previously)    
  5. for ( var i in properties ) {     
  6.     (function(){    
  7.         //using this here is wrong 这里用this是错误的,因为这时this的作用域是匿名函数的    
  8.         // Create a new getter for the property    
  9.         this"get" + i ] = function() {  
  10.             //这里用properties[i]也是错误的,因为properties[i]作用域是在闭包的外面  
  11.             return properties[i];    
  12.         };    
  13.         // Create a new setter for the property    
  14.         this"set" + i ] = function(val) {    
  15.             properties[i] = val;    
  16.         };    
  17.     })(); }    
  18. }    
  19. // Create a new user object instance and pass in an object of    
  20. // properties to seed it with    
  21. var user = new User({    
  22.     name: "Bob",    
  23.     age: 44    
  24. });    
  25. // Just note that the name property does not exist, as it's private    
  26. // within the properties object    
  27. alert( user.name == null );    
  28. // However, we're able to access its value using the new getname()    
  29. // method, that was dynamically generated    
  30. alert( user.getname() == "Bob" );    
  31. // Finally, we can see that it's possible to set and get the age using    
  32. // the newly generated functions    
  33. user.setage( 22 );    
  34. alert( user.getage() == 22 );    

这段代码应该是有几处错误的,如红色字体所示,this的作用域是匿名函数的;另一处是properties[i],它的scope是匿名函数外面,所以,代码执行将会不正确。

经过一番调试,应该写成这样:

 
  1. function User( properties ) {    
  2.     //这里一定要声明一个变量来指向当前的instance    
  3.     var objthis = this;    
  4.     for ( var i in properties ) {    
  5.         (function(){    
  6.                 //在闭包内,t每次都是新的,而 properties[i] 的值是for里面的    
  7.                 var t = properties[i];    
  8.                 objthis[ "get" + i ] = function() {return t;};    
  9.                 objthis[ "set" + i ] = function(val) {t = val;};    
  10.         })();     
  11.     }    
  12. }    
  13.     
  14. //测试代码    
  15. var user = new User({    
  16.     name: "Bob",    
  17.     age: 44    
  18. });    
  19.     
  20. alert( user.getname());    
  21. alert( user.getage());    
  22.     
  23. user.setname("Mike");    
  24. alert( user.getname());    
  25. alert( user.getage());    
  26.     
  27. user.setage( 22 );    
  28. alert( user.getname());    
  29. alert( user.getage());    
 这样,代码就是按预想的执行了。 希望对闭包的理解有所帮助。

Tags:

posted @ Friday, March 06, 2009 12:00 AM

Print

Comments on this entry:

# re: javascript closure(闭包)的一个示例

Left by 世玉 at 9/27/2009 11:24 AM
Gravatar
谢谢,帮助很大~

另指出一点小错误:
“//using this here is wrong 这里用this是错误的,因为这时this的作用域是匿名函数的 ”
——这句解释是不对的。因为:匿名函数的this,始终指向window对象。这是我刚刚在
www.macji.com/.../javascript-this-keyword-tips/ 看到的。自己也测试过。

# re: javascript closure(闭包)的一个示例

Left by 世玉 at 9/27/2009 11:27 AM
Gravatar
呃。。怪我粗心。。
你并没有说“this指向匿名函数”,而是说“this的作用域是匿名函数的” 貌似也没错

Your comment:



 (will not be displayed)


 
 
 
Please add 6 and 1 and type the answer here:
 

Live Comment Preview:

 
View posts by date
«March»
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910