诡异的js闭包问题的解决.

错误代码:

Java代码 复制代码
  1. function User( properties ) {      
  2.     var temp=this;      
  3.     for ( var i in properties ) { (function(){      
  4.      
  5.         temp[ "get" + i ] = function() {      
  6.             return properties[i];      
  7.         };      
  8.      
  9.         temp[ "set" + i ] = function(val) {      
  10.             properties[i] = val;      
  11.         };      
  12.     })(); }      
  13. }      
  14.      
  15. var user = new User({      
  16.     name: "Bob",      
  17.     age: 44      
  18. });      
  19. alert( user.getname() );      
  20.      
  21. alert( user.getage());    
function User( properties ) {   
    var temp=this;   
    for ( var i in properties ) { (function(){   
  
        temp[ "get" + i ] = function() {   
            return properties[i];   
        };   
  
        temp[ "set" + i ] = function(val) {   
            properties[i] = val;   
        };   
    })(); }   
}   
  
var user = new User({   
    name: "Bob",   
    age: 44   
});   
alert( user.getname() );   
  
alert( user.getage());  



此时的结果将会打印出两个44,有关这点g9的blog上这样的解答:

引用

JavaScript的Closure环境由静态的句法结构确定。也就是说,代码一旦写成,我们就知道函数的自由变量同哪些环境里的变量绑定。因此,虽然运行时同一个内函数被调用多次,创建了多个闭包,这些闭包指向的都是同一个环境里的同一个变量。这样同JavaScript规定的闭包语义一致。



这句不是很理解,望那个达人能够解释一下.

于是我们进行改进我们可以加进去一个叫做factor function的东东。
请看改写后的代码.

Java代码 复制代码
  1. function User( properties ) {      
  2.     var temp=this;      
  3.     for ( var i in properties ) {    
  4.     (function(i){      
  5.         temp[ "get" + i ] = function() {      
  6.             return properties[i];      
  7.         };      
  8.         temp[ "set" + i ] = function(val) {      
  9.             properties[i] = val;      
  10.         };      
  11.     })(i);    
  12.     }   
  13. }      
  14.      
  15. var user = new User({      
  16.     name: "Bob",      
  17.     age: 44      
  18. });      
  19.      
  20.      
  21. alert( user.getname());     
  22. user.setname("bobo");   
  23. alert(user.getname());    
  24. alert( user.getage());    
function User( properties ) {   
    var temp=this;   
    for ( var i in properties ) { 
	(function(i){   
        temp[ "get" + i ] = function() {   
            return properties[i];   
        };   
        temp[ "set" + i ] = function(val) {   
            properties[i] = val;   
        };   
    })(i); 
	}
}   
  
var user = new User({   
    name: "Bob",   
    age: 44   
});   
  
  
alert( user.getname());  
user.setname("bobo");
alert(user.getname()); 
alert( user.getage());  



这样就可以打印出正确的结果了.

<script type="text/javascript"></script> <script src="http://a.alimama.cn/inf.js" type="text/javascript"></script>
评论
5 楼 jindw 2008-08-13   回复
你要先知道一个让很多人服略的情况。
javascript只有函数变量,没有块变量。

你的闭包外共享的是同一个函数变量。
4 楼 dennis_zane 2007-09-20   回复
这里应该是创建的两个闭包共享自由变量i
3 楼 咖啡豆子 2007-09-09   回复
我觉得闭包里绑定的是变量而不是变量的值,所以第一次这样写以后:
# temp[ "get" + i ] = function() {    
#             return properties[i];    
#         };
并没有将properties["name"]绑定给this.getname.
第二次绑定this.getage的时候是同样道理,i最后的值是"age",所以两个getter在使用的时候都是properties["age"],好象i不会被垃圾收集,因为它被闭包使用了.不知道我的理解对不对?
2 楼 Lich_Ray 2007-09-05   回复
引用
这句不是很理解,望那个达人能够解释一下.

已经没法儿解释了,除非你不知道闭包变量是什么。
1 楼 笨笨狗 2007-09-05   回复
这是因为在外层闭包里面又生成了个闭包,然后是通过参数传递变量进去的,其实这么写更容易理解:
Java代码 复制代码
  1. function User( properties ) {        
  2.     var temp=this;        
  3.     for ( var i in properties ) {      
  4.         (function(j){        
  5.             temp[ "get" + j ] = function() {        
  6.                 return properties[j];        
  7.             };        
  8.             temp[ "set" + j ] = function(val) {        
  9.                 properties[j] = val;        
  10.             };        
  11.         })(i);      
  12.     }     
  13. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值