先放一个题外话:
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),这时必定要当心,不要随便改变父函数内部变量的值函数
来源:我将枕中记忆抹去任岁月浮光掠影性能