• 由javascript中"匿名函数调用写法"引出的一些东东


    匿名函数自动调用的三种写法如下:

    var f1 = function(){alert("f1");}();
    
    (function(){alert("f2");}());
    
    void function(){alert("f3");}();
    

    再来看一段代码:

    function Person(properties){
    	for(var p in properties){				
    		(function(context){	
    			var t = p;
    			context["get" + t] = function(){return properties[t];}
    			context["set" + t] = function(val){properties[t] = val;}
    		}(this));
    	}
    }
    
    var p = new Person({name:"菩提树下的杨过",sex:"男"});
    alert(p.getname());//弹出"菩提树下的杨过"
    alert(p.getsex());//弹出"男"
    alert(p.name);//弹出:undefined
    

    Person类为所有传入的对象属性,自动生成了getXXX与setXXX方法,这一段代码虽然很短,却包含了诸多js中的关键概念:

    1.json对象表示法

    当我们把"{name:"菩提树下的杨过",sex:"男"}"做为参数,传入Person构造函数时,实际上就建立了一个字典结构的键值对:

    name --> "菩提树下的杨过"
    sex --> "男"

    即  name - value 结构,所以也就能用for ...in语句来遍历了

    以上结论,可以这样测试

    var obj = {name:"菩提树下的杨过",sex:"男"};
    for(var p in obj){
        alert("名称:" + p + ",值:" + obj[p]);
    }
    

    2.匿名函数的自动调用

    这一段代码结构可以简化为:

    function Person(properties){
    for(var p in properties){    
        (  
          function(){ 
           ...
          }()  
        );
      }
    }
    


    可以看到,里面其实就是调用了匿名函数(即文章最开头的第二种写法)

    3.函数调用时的上下文关系

    每个函数调用时总会关联一个上下文(如果找不到上下文,则最终会关联到window对象)

    function foo(fn){   
     //this.barbar = "Foo.barbar";
     if (typeof fn === "function"){
      fn();
     } 
    }
    
    var bar = {
     barbar : "Hello,World!",
     method:function(){    
      alert(this.barbar);
     }
    }
    
    bar.method(); //调用时,medhod中的this指的就是bar对象的上下文,此时this.barbar 与 bar.barbar等效  
    
    foo(bar.method);//调用时,这时bar.method中的this指代的是foo内部的上下文,而foo中并没有barbar的定义,因此最终this.barbar其实就是foo.barbar,所以会弹出"undefined",如果把foo中的注释行去掉注释,就更能映证这一点
    
    

    这是最近网上热传的"javascript令人费解的10件事"中的一段代码,我在注释中加了自己的理解,再回到文中的代码,代码的本意是想让Person类动态添加对所有的属性的getXXX与setXXX方法(通过匿名函数的自动调用),而匿名函数在执行时getXXX与setXXX函数的上下文this默认是指向匿名函数的,而非Person类本身!为了解决这个问题,不得不在匿名函数中增加了一个参数context,并且在调用时用(function(...){}(this));把Person的上下文this传入到匿名函数中

    4.闭包
    关于闭包,不再做过多的学术解释,先给一段代码:

    <ul>
     <li id="a1">aa</li>
     <li id="a2">aa</li>
     <li id="a3">aa</li>
    </ul>
    
    <script type="text/javascript">
    
    for (var i=1;i<= 3;i++){
     var li = document.getElementById("a" + i);
     li.onclick = function(){
      alert(i);
     }
    }
    
    </script>
    
    

    解释onclick生成了一个匿名函数,并引用外层的变量i,形成闭包,造成变量i在该函数中共享(可以理解为三个li的onclick函数中都引用同一个变量i),而i在循环结束后,变成4,因此所有li最终点击都是弹出4

    解决办法:

    <script type="text/javascript">
    for (var i=1;i<= 3;i++){
     var li = document.getElementById("a" + i);
     li.i = i;
     li.onclick = function(){    
      alert(this.i);
     }
    }
    </script>
    

    再回到文中的代码,同样匿名函数引用外层的变量p,形成闭包,如果不用var t = p;中转一下变量,则最后所有的getXXX与setXXX方法,都是对应最后一个属性的.

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    文本省略并显示省略号
    屏蔽IOS端alert窗口带URL的方法
    vue实现打印功能
    使用vue-cli搭建vue项目
    四元表达式
    循环数组中的对象 放进另一个数组对象里面
    vue中选择图片,预览图片,返回base64
    上传图片,预览并保存成blob类型 和 base64
    【HbuilerX-Bug】终端无法显示打印信息,也无法输入
    el-tag标签使用三元表达动态改变type类型
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1675206.html
Copyright © 2020-2023  润新知