闭包
学习闭包的时候有一种似懂非懂奥妙的感觉
函数在调用的时候会创建自己的作用域链跟活动对象
而内部函数是作用域链总是内部活动对象优先然后外部函数活动对象第二位外部函数外部函数活动对象一直到全局作用域
var helloword = 'today is a good day';
function sayhi(){
var helloword = 'hello world';
function hello(){
console.log(helloword);
}
}
在sayhi函数里面如果没有变量helloword那么hello就会继续往上找 知道找到helloword这个变量 否则则会输出undefined
基本作用域的概念说了一下
然后现在谈闭包
闭包即是指有权访问另一个函数作用域中的变量的函数
function foo(){
var result = new Array();//创建了一个数组
for(var i=0;i<10;i++){
result[i]=function(){
return i;
};
}
}
这段是高程3的代码
这段代码的本意是要返回一个键值对相同索引的数组
而事实上这段代码返回数组的值都为10
这里要知道一个东西 return i跟result[i]引用的都是i 而i最终状态值为10
所以返回的都是10很理所当然
result[i]=function(){ return i; }; <===========修改成=============>
result[i]=function(num){ return function(){ return num; }; }(i); 这相当于是将每一次引用的值做一个复制再传递。
这样就能符合预期的效果了
函数嵌套 内层函数可以调用外部函数的变量这是作用域可以被允许的(即使外层函数已经运行完毕了) 因为外部函数的变量跟值也在内层函数作用域内 这就是闭包
闭包能使函数内的变量不被释放 因为函数内部创建闭包时候 对函数内部的活动对象有引用时候 js的垃圾回收机制在活动对象引用数仍为1的时候是不会释放变量的
eg: function Foo(){ var element=document.getElementById('ID'); var id = element.id; element.onclick=function(){ alert(id); }; element.id=null; } 必须手动设置element.id为null释放引用 这样才可以减少引用数释放内存