Javascript闭包实例详解闭包实例详解
什么是闭包什么是闭包
闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性。但是闭包也不是什么复杂到不可理解的东西,简而言之,
闭包就是:
闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配当在一个
函数内定义另外一个函数就会产生闭包上面的第二定义是第一个补充说明,抽取第一个定义的主谓宾——闭包是函数的‘局部
变量’集合。只是这个局部变量是可以在函数返回后被访问。(这个不是官方定义,但是这个定义应该更有利于你理解闭包)
理解Javascript的闭包非常关键,本篇试图用最简单的例子理解此概念。
function greet(sth){
return function(name){
console.log(sth + ' ' + name);
}
}
//hi darren
greet('hi')('darren');
或者可以写成这样:
var sayHi = greet('hi');
sayHi('darren');
我们要提的问题是:为什么greet的内部函数能使用sth这个变量?
其内部大致运作如下:
→ 创建全局上下文
→ 执行var sayHi = greet(‘hi’);语句,创建greet上下文,变量sth存储在greet上下文中。
→ 继续执行greet函数内的语句,返回一个匿名函数,虽然greet上下文从堆栈上消失,但sth变量依旧存在于内存的某个空
间。
→ 继续执行sayHi(‘darren’);创建了sayHi上下文,并试图搜寻sth变量,但在sayHi这个上下文中没有sth变量。sayHi上下文会
沿着一个作用域链找到sth变量对应的那个内存。 外层函数就像一个闭包,其内部函数可以使用外部函数的变量。
一个闭包的简单例子
function buildFunctions(){
var funcArr = [];
for(var i = 0; i < 3; i++){
funcArr.push(function(){console.log(i)});
}
return funcArr;
}
var fs = buildFunctions();
fs[0](); //3
fs[1](); //3
fs[2](); //3
以上,为什么结果不是0, 1, 2呢?
–因为i作为一个闭包变量,当前值为3,被内部函数使用。要实现想要的效果,可以在遍历的时候每一次遍历创建一个独立的
上下文使其不受闭包影响。而自触发函数可以实现独立上下文。
function buildFunctions(){
var funcArr = [];
for(var i = 0; i < 3; i++){
funcArr.push((function(j){
return function(){
console.log(j);
};
}(i)));
}
return funcArr;