zoukankan      html  css  js  c++  java
  • javascript closure(闭包)的一个示例

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

     1 // Create a new user object that accepts an object of properties  
     2function User( properties ) {  
     3// Iterate through the properties of the object, and make sure  
     4// that it's properly scoped (as discussed previously)  
     5for ( 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  
    21var 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  
    27alert( user.name == null );  
    28// However, we're able to access its value using the new getname()  
    29// method, that was dynamically generated  
    30alert( user.getname() == "Bob" );  
    31// Finally, we can see that it's possible to set and get the age using  
    32// the newly generated functions  
    33user.setage( 22 );  
    34alert( user.getage() == 22 ); 

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

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

     1function 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//测试代码  
    15var user = new User({  
    16    name: "Bob",  
    17    age: 44  
    18}
    );  
    19  
    20alert( user.getname());  
    21alert( user.getage());  
    22  
    23user.setname("Mike");  
    24alert( user.getname());  
    25alert( user.getage());  
    26  
    27user.setage( 22 );  
    28alert( user.getname());  
    29alert( user.getage()); 

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


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

  • 相关阅读:
    时间复杂度和空间复杂度
    七、vue计算属性
    六、vue侦听属性
    四、vue派发更新
    五、vue nextTick
    三、vue依赖收集
    二、vue响应式对象
    递归
    链表
    TypeScript类型定义文件(*.d.ts)生成工具
  • 原文地址:https://www.cnblogs.com/jinweijie/p/1376510.html
Copyright © 2011-2022 走看看