javascript closure(闭包)的一个示例

时间:2020-12-08 22:47:45

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

 

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

 

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

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

 

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

 

 这样,代码就是按预想的执行了。


ps: blog搬家,欢迎访问新地址:www.jinweijie.com