闭包
有权访问另一个函数作用域中的变量的函数。
作用域链
(关于执行环境是啥,个人理解一层函数就是一个执行环境)
每层执行环境(又称环境)都有一个变量对象,存储着只属于该层环境的所有变量和函数。而函数的作用域链本质是一个指针列表,依次指向外面层层环境的变量对象。
当一个函数被创建,会预先创建一个作用域链,存于函数的[[scope]]内部属性中。当函数被调用时,取[[scope]]里的作用域链,再把自己的活动对象(函数的变量对象叫活动对象)推到作用域链的最前端,构成一个完整的作用域链。
函数的变量对象只在函数被调用时存在。但是由于return了匿名函数,函数的活动对象一直被匿名函数的作用域链引用着。根据浏览器的引用计数垃圾回收原理,外层函数的活动对象将得不到释放,导致所谓的内存泄漏,而该匿名函数就是一个闭包。这就是为什么大家说闭包容易导致内存泄漏。
关于闭包里的this指向,只要使用以下原则分析即可:
所有函数的this和arguments这俩自带的变量,不会像别的变量一样往上层作用域去搜索,“只会搜索到其活动对象为止”。
举个栗子:
window.name = 'winow';
var testFn = function(){
var name = 1;
return function(){ console.log(this.name)}
}
var f = testFn();
f(); //'win'
var obj = {name:'obj',objFn:f};
obj.objFn(); //'obj'