• javascript中的闭包、模仿块级作用域和私有变量


      闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式为:在一个函数内部创建另一个函数。

      “当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象(activation object).但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象出于第三位。。。。。直至作用域链终点的全局执行环境。”

    function creawteComparisonFunction(propertyName){
           return function(object1,object2){
                 var value1=object1[propertyName];
                 var value2=object1[propertyName];
                 if(value1<value2){
                       return -1;
                 }else if(value1>value2){
                       return 1;   
                 }else{
                       return 0;
                 }
          };  
    }

      在匿名函数从createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。更重要的是,createComparisonFunction()函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。或者说,当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然留在内存在,直到匿名函数被销毁后:

    //创建函数
    var compareNames=creawteComparisonFunction("name");
    //调用函数
    var result=compareName({name:"gay1"},{name:"gay2"});
    //解除对匿名函数的引用(以便释放内存)
    compareNames=null;

    请看如下代码:

    function createFunctions(){
          var result=new Array();
          for(var i=0;i<10;i++){
                result[i]=function(){
                      return i;    
                };   
          }
          return result;
    }

    首先得确定:这段代码创建了10个闭包,但结果却不是我们想要的,要达到目的,可以这样:

    function createFunctions(){
          var result=new Array();
          for(var i=0;i<10;i++){
                result[i]=function(num){
                      return function(){
                            return num;
                      };
                }(i);   
          }
          return result;
    }

    在这个版本中,没有直接把闭包复制给数组,而是定义了一个匿名函数,并将立即执行改匿名函数的结果赋值给数组。这里的匿名函数有一个参数num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量i。由于函数参数是按值传递的,所以就会将变量i的当前值复制给参数num。而在这个匿名函数内部,又创建并返回。了一个反问num的闭包。这样一来,result数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了。

      “javascript没有块级作用域的概念。” 但是可以使用“私有作用域”的匿名函数语法来打到目的:

    function outputNumber(count){
         (function(){
               for(var i=0;i<count;i++){
                     alert(i);
               }
         })();
         alert(i);  //报错, 但是如果不实用私有作用域,则正常
    }

    “私有变量”大家一定比我更了解这个,这里就不谈了。注意一个坑就好:

    function Person(name){
        this.getName=function(){
            return name;
        };
        this.setName=function(value){
            name=value;
        };
    }
    var person1=new Person("gay1");
    alert(person1.getName());
    var person2=new Person("gay2");
    alert(person2.getName());
    person1.setName("gay3");
    alert(person1.getName());    //gay3
    alert(person2.getName());    //gay2
    
    /**************邪恶的分割线***********************/
    
    (function(){
        var name="";
        Person=function(value){
            name=value;
        };
        Person.prototype.getName=function(){
            return name;
        };
        Person.prototype.setName=function(value){
            name=value;
        };
    })();
    var person1=new Person("gay1");
    alert(person1.getName());
    person1.setName("gay2");
    alert(person1.getName());
    
    var person2=new Person("gay3");
    alert(person1.getName());    //gay3
    alert(person2.getName());    //请注意这里是gay3
  • 相关阅读:
    测分用例模板
    功能测试用例设计(24方法)
    pycharm
    Mac-peizhi
    基于Java BufferedImage实现识别图片中的黑色矩形
    Soap从入门到实战
    实列+JVM讲解类的实列化顺序
    基于Springboot的BaseService和BaseController
    Kendo-Grid for Vue API and Template
    web项目jsp中无法引入js问题
  • 原文地址:https://www.cnblogs.com/nullcnb/p/3760068.html
Copyright © 2020-2023  润新知