美文网首页javascript
JavaScript中闭包与this对象

JavaScript中闭包与this对象

作者: 若隐爱读书 | 来源:发表于2019-06-30 22:26 被阅读38次

    闭包

    闭包与匿名函数容易混淆。闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数

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

    在上面的例子中,3、4行定义value1 value2的过程中,调用了外部函数中的变量propertyName。即使这个内部函数返回了,而且在其他地方调用了,但仍可以访问变量propertyName。之所以能够访问这个变量,是因为内部函数的作用域链中包含createComparisonFunction()的作用域。要搞清楚其中的内容,就要从理解函数被调用的时候发生了什么入手。
    当某个函数被调用时,会创建一个执行环境,以及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三级。

    变量

    作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。下面的例子可以清晰的说明这个问题。

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

    这个函数会返回一个函数数组,表面上看似乎会返回[0,1,...]。但实际上却是返回了[10,10,...],因为每个函数的作用域链中都保存着createFunctions()函数的活动对象,所以它们引用的都是同一变量i,所以它们引用的都是同一个变量i,所以最后返回都是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的闭包。这样一来,数组中每个值就可以获取num的一个副本,因此就会有不同的返回值了。

    this对象

    在闭包中使用this对象也可能导致一些问题。this对象是在运行时绑定的,匿名函数的执行环境具有全局性,因此其this往往指向window。但有时候由于闭包编写方式不同,这一点可能也不明显。

    var name ="The Windows";
    var object = {
        name: "My object",
        getNameFunc: function(){
            return function(){
                return this.name;
            }
        }
    }
    object.getNameFunc()();//The Windows
    

    object.getNameFunc()返回了一个匿名函数,然后调用执行这个匿名函数。因为这个匿名函数不是作为某个对象的方法来调用执行,所以它的this就是wlndow对象.

    var name ="The Windows";
    var object = {
        name: "My object",
        getNameFunc: function(){
            var that = this;
            return function(){
                return that.name;
            }
        }
    }
    object.getNameFunc()();//My Object
    

    在定义匿名函数之前,我们把this对象赋值给一个that。定义闭包之后,闭包也可以访问这个变量。因此,就可以获得object的变量name。

    相关文章

      网友评论

        本文标题:JavaScript中闭包与this对象

        本文链接:https://www.haomeiwen.com/subject/fgyhcctx.html