您的位置:首页 > Web前端 > JavaScript

Javascript 的闭包如何工作?

2015-05-17 22:39 274 查看
原文地址:How do javascript closures work?

任何时候当你看到函数关键字中有另外一个函数时,里面的函数都可以方位外部的函数。

function foo(x) {
var tmp = 3;

function bar(y) {
alert(x + y + (++tmp)); // will alert 16
}

bar(10);
}

foo(2);


结果总是16,因为
bar
可以方位
x
,x在
foo
中被定义为一个参数。

这就是闭包。函数不一定返回,从而叫做闭包。

function foo(x) {
var tmp = 3;

return function (y) {
alert(x + y + (++tmp)); // will also alert 16
}
}

var bar = foo(2); // bar is now a closure.
bar(10);


上面的函数也会返回16,因为
bar
仍然可以引用
x
tmp
,尽管不直接存在于作用域中。

然而,因为
tmp
仍然存在与
bar
的闭包中。它也会增加。每次你调用
bar
时,他都会增加。下面是一个关于闭包的简单例子:

var a = 10;
var b = 6;

function test() {
console.log(a); // will output 10
console.log(b); // will output 6
}

test();


当Javascript函数被调用时,一个新的执行上下文被创建。连同函数参数和父对象, 这个执行上下文也接受所有的外部声明(在上面的例子中,‘a’和‘b’都是)

有可能创建不止一个闭包函数,或者通过设置它们的全局变量返回它们的列表。这些都有一个相同的
x
和相同的
tmp
,他们没有复制自己。

这个数字
x
是数字字面量。作为在Javascript的其他字面量,当
foo
被调用时,这个数字
x
被作为参数复制到了
foo


另一方面,Javascript在处理对象时总是使用参考引用。也就是说,你通过对象调用
foo
,闭包返回最初对象的引用。

function foo(x) {
var tmp = 3;

return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}

var age = 2;
var bar = foo(age); // bar is now a closure referencing age.
bar(10);


正如期望的,每次调用
bar(10)
都会增加
x.memb
。没有预料的是,
x
简单引用同一个对象作为
age
的变量。通过几次调用
bar
后,
age.memb
将会是2! 这参考对HTML对象的内存泄露的基础。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  闭包 javascript