有很多人搞不清匿名函数和闭包这两个概念,经常混用。闭包是指有权访问另一个函数作用域中的变量的函数。匿名函数就是没有实际名字的函数。
闭包
概念
闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作搬在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止,其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。
条件
闭包是允许函数访问局部作用域之外的数据。即使外部函数已经退出,外部函数的变量仍可以被内部函数访问到。
因此闭包的实现需要三个条件:
内部函数实用了外部函数的变量
外部函数已经退出
内部函数可以访问
function a() {
var x = 0;
return function(y) {
x = x + y;
// return x;
console.log(x);
}
}
var b = a();
b(1); //1
b(1); //2
上述代码在执行的时候,b得到的是闭包对象的引用,虽然a执行完毕后,但是a的活动对象由于闭包的存在并没有被销毁,在执行b(1)的时候,仍然访问到了x变量,并将其加1,若再执行b(1),则x是2,因为闭包的引用b并没有消除。(后面会解释,闭包返回了函数,函数可以创建独立的作用域)
闭包,其实就是指程序语言中能让代码调用已运行的函数中所定义的局部变量。
但是你只需要知道应用的两种情况即可——函数作为返回值,函数作为参数传递。
function fn() {
var max = 10;
return function bar(x) {
if (x > max) {
console.log(x);
}
};
}
var f1 = fn();
f1(15);
如上代码,bar函数作为返回值,赋值给f1变量。执行f1(15)时,用到了fn作用域下的max变量的值。至于如何跨作用域取值,可以参考上一篇文章。
var max = 10,
fn = function(x) {
if (x > max) {
console.log(x); //15
}
};
(function(f) {
var max = 100;
f(15);
})(fn);
如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(15)时,max变量的取值是10,而不是100。
上一篇讲到自由变量跨作用域取值时,曾经强调过:要去创建这个函数的作用域取值,而不是“父作用域”。理解了这一点,以上两端代码中,自由变量如何取值应该比较简单.
另外,讲到闭包,除了结合着作用域之外,还需要结合着执行上下文栈来说一下。
在前面讲执行上下文栈时,我们提到当一个函数被调用完成之后,其执行上下文环境将被销毁,其中的变量也会被同时销毁。
有些情况下,函数调用完成之后,其执行上下文环境不会接着被销毁。这就是需要理解闭包的核心内容。
闭包
概念
闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作搬在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止,其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。
条件
闭包是允许函数访问局部作用域之外的数据。即使外部函数已经退出,外部函数的变量仍可以被内部函数访问到。
因此闭包的实现需要三个条件:
内部函数实用了外部函数的变量
外部函数已经退出
内部函数可以访问
function a() {
var x = 0;
return function(y) {
x = x + y;
// return x;
console.log(x);
}
}
var b = a();
b(1); //1
b(1); //2
上述代码在执行的时候,b得到的是闭包对象的引用,虽然a执行完毕后,但是a的活动对象由于闭包的存在并没有被销毁,在执行b(1)的时候,仍然访问到了x变量,并将其加1,若再执行b(1),则x是2,因为闭包的引用b并没有消除。(后面会解释,闭包返回了函数,函数可以创建独立的作用域)
闭包,其实就是指程序语言中能让代码调用已运行的函数中所定义的局部变量。
但是你只需要知道应用的两种情况即可——函数作为返回值,函数作为参数传递。
function fn() {
var max = 10;
return function bar(x) {
if (x > max) {
console.log(x);
}
};
}
var f1 = fn();
f1(15);
如上代码,bar函数作为返回值,赋值给f1变量。执行f1(15)时,用到了fn作用域下的max变量的值。至于如何跨作用域取值,可以参考上一篇文章。
var max = 10,
fn = function(x) {
if (x > max) {
console.log(x); //15
}
};
(function(f) {
var max = 100;
f(15);
})(fn);
如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(15)时,max变量的取值是10,而不是100。
上一篇讲到自由变量跨作用域取值时,曾经强调过:要去创建这个函数的作用域取值,而不是“父作用域”。理解了这一点,以上两端代码中,自由变量如何取值应该比较简单.
另外,讲到闭包,除了结合着作用域之外,还需要结合着执行上下文栈来说一下。
在前面讲执行上下文栈时,我们提到当一个函数被调用完成之后,其执行上下文环境将被销毁,其中的变量也会被同时销毁。
有些情况下,函数调用完成之后,其执行上下文环境不会接着被销毁。这就是需要理解闭包的核心内容。