一、回顾
作用域:局部变量不能在全局访问
作用域链:函数执行时会动态创建该调用函数的作用域链(自内向外)
函数被调用时,将其函数的变量对象存入执行环境栈中,当该函数执行完成后,将其从栈中弹出(垃圾回收机制)
函数调用时会动态创建执行环境和作用域链,并开始初始化活动对象
二、闭包
(1)为什么要使用闭包?
突破作用域的限制,有权访问另一个函数作用域中的变量的函数。
(2)实现的原理
通过引用函数内部的函数
(3)为什么?
与函数的执行相关
var person = function() {
var personnum = 0; //私有privite,外部不能直接访问
function getCount() {
return personnum++;
}
return getCount;
}
var p = person();
var num=p();
调用函数person时,创建执行环境和作用域链,然后初始化活动对象,此时外部person函数返回内部函数personnum给p如下图
当p被调用时相当于执行person函数内部函数personnum, 如图
调用函数时都会新开辟一个空间,图中绿色框内则为每次引用函数内部的函数,通过作用域链来实现对函数内部的变量进行访问
function constfunc(){
var funcs=[];
for(var i=0;i<10;i++){
funcs[i]=function(){return i;}
}
return funcs;
}
var funcs=constfunc();
console.log(funcs[5]());
//
function constfunc(){
var result=[];
for(var i=0;i<10;i++){
result[i]=function(num){
return function(){
return num;
}
}(i);
}
return result;
}
var p=constfunc();
for(var i=0;i<10;i++){
console.log(p[i]());
}
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; console.log(object.getNameFunc()());
//
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
console.log(object.getNameFunc()());
每个函数在被调用时,其活动对象都会自动取得两个特殊变量:this和arguments.内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的两个变量。只有通过把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象。