闭包

先放一个题外话:
node环境 亲测结果: for(var i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 每隔一秒输出一个 5,共输出五个5。 for(let i=0;i<5;i++){ setTimeout(function(){ console.log(i); },1000); } 每隔一秒输出一个 数,0 1 2 3 4。

谷歌浏览器环境 亲测结果:
for(var i=0;i<5;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}
先输出一个10,而后每隔一秒输出一个5,共输出五个5。
for(let i=0;i<5;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}
先输出一个5,而后每隔一秒输出一个数,依次是0 1 2 3 4。
复制代码
复制代码
谷歌浏览器环境 亲测结果:
var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        return function(){
            return this.name;
        };
    }
};
console.log(object.getNameFunc()());
输出 "The Window"

console.log(object.getNameFunc().call(object));
输出 "My Object"
复制代码
复制代码
这个相对简单一点:
var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        var that = this;
        return function(){
            return that.name;
        };
    }
};
console.log(object.getNameFunc()());
输出 "My Object"
复制代码
复制代码
这两个更简单:
var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : ()=>{
        console.log(this.name);
    }
};
object.getNameFunc();
输出 The Window
undefined
var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        console.log(this.name);
    }
};
object.getNameFunc();
输出 My Object
复制代码
复制代码
var name = 'global';

var obj = {
    name : 'obj',
    dose : function(){
        this.name = 'dose';
        return function(){
            return this.name;
        }
    }
}

console.log(obj.dose()());
输出 global
console.log(obj.dose().call(this))
输出 global
console.log(obj.dose().call(window))
输出 global
console.log(obj.dose().call(obj))
输出 dose

注意:把下面一行拆分(相似的均可以拆分)
obj.dose().call(this)
拆分为:
var xxx = obj.dose();
xxx.call(this);
复制代码
复制代码
var name = 'global';

var obj = {
    name : 'obj',
    dose : function(){
        this.name = 'dose';
        return function(){
            return this.name;
        }.bind(this)
    }
}

console.log(obj.dose().call(this));
输出 obj
注意:因为return的function中用了bind,因此至关于固定了this,外边再call什么进来,也只是碍眼法而已。IE认为在return中用bind不常见,兼容性也不高,因此上面内容能够改写以下:
var name = 'global';

var obj = {
    name : 'obj',
    dose : function(){
        var that = this;
        this.name = 'dose';
        return function(){
            return that.name;
        }
    }
}

console.log(obj.dose().call(this));
输出 obj
    
复制代码

用处:闭包能够用在许多地方。它的最大用处有两个,一个是前面提到的能够读取函数内部的变量,另外一个就是让这些变量的值始终保持在内存中。node

注意点:浏览器

1)因为闭包会使得函数中的变量都被保存在内存中,内存消耗很大,因此不能滥用闭包,不然会形成网页的性能问题,在IE中可能致使内存泄露。解决方法是,在退出函数以前,将不使用的局部变量所有删除。闭包

2)闭包会在父函数外部,改变父函数内部变量的值。因此,若是你把父函数看成对象(object)使用,把闭包看成它的公用方法(Public Method),把内部变量看成它的私有属性(private value),这时必定要当心,不要随便改变父函数内部变量的值函数

来源:我将枕中记忆抹去任岁月浮光掠影性能

相关文章
相关标签/搜索