Javascript 的闭包如何工作?

本文深入解析JavaScript中的闭包概念,包括闭包如何保留对外部作用域变量的引用,即使在外部函数已经执行完毕的情况下也是如此。文章还探讨了闭包在实际编程中的应用,并通过实例演示了闭包的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址: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仍然可以引用xtmp,尽管不直接存在于作用域中。

然而,因为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对象的内存泄露的基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值