javascript闭包和作用域

60 篇文章 0 订阅
55 篇文章 1 订阅

闭包是javascript的显著特征。虽然许多JavaScript开发者在开发时没有理解闭包的主要优势,但是使用闭包,不仅可以通过减少代码数量和复杂度来添加高级特性,还能实现不太可能完成的功能。换句话说,如果没有闭包,事情将变得非常复杂。例如,如果没有闭包,事件处理和动画等包含回调函数的任务,它们的实现变得复杂的多。除此以外,如果没有闭包,将完全不可能实现私有变量。

 

闭包允许函数访问并操作函数外部的变量。只要变量或函数存在于声明函数时的作用域内,闭包即可使函数能够访问这些变量或函数。

注意:

或许你已经熟悉了作用域的概念,但是,有时作用域指的是在程序的特定部分中标识符的可见性。作用域是程序的一部分,特定的名字绑定特定的变量。这可能看起来很直观,但是要记住,所声明的函数可以在声明之后的任何时间被调用,甚至当该函数声明的作用域消失之后仍然可以调用。

//在全局作用域中定义一个变量
var outerValue = "ninjaTest";
//在全局作用域中声明函数
function outerFunction() {
  if (outerValue === 'ninjaTest') {
    console.log("I can see the ninjaTest.");
  }
}
outerFunction();//执行该函数

 

 

上述代码中,在同一作用域声明了变量outerValue以及外部函数outerFunction,是全局作用域。然后,执行外部函数outerFunction。该函数可以“看见”并访问变量outerValue。

因为外部变量outerValue和外部函数outerFunction都是全局作用域中声明的,该作用域(实际上就是一个闭包)从未消失(只要应用处于运行状态)。这也不足为奇,该函数可以访问到外部变量,因此它仍然在作用于内并且是可见的。

虽然闭包存在,但是闭包的优势仍然不明显。

var outerValue = 'samurai';
var later;//声明一个空变量,稍后在后面的代码中使用

function outerFunction() {
  //在函数内部声明一个值,该值在作用域局限于函数内部,在函数外部不允许访问
  var innerValue = "ninjaTest";

  //在outerFunction函数中声明一个内部函数,声明该内部函数时,innerValue是在内部函数的作用域内的。
  function innerFunction() {
    if (outerValue === 'samurai') {
      console.log("I can see the samurai.");
    }
    if (innerValue === 'ninjaTest') {
      console.log("I can see the ninjaTest.");
    }
  }

  //将内部函数innerFunction的引用存储在变量later上,因为later在全局作用域内,所以我们可以对它进行调用
  later = innerFunction;
}

//调用outerFunction函数,创建内部函数innerFucntion,并将内部函数赋值给变量later。
outerFunction();
//通过later调用内部函数。我们不能直接调用内部函数,因为它的作用域(和innerValue一起)被限制在外部函数outerFunction之内。
later();

 

是什么使得在内部函数的作用域消失之后再执行内部函数时,其内部变量仍然存在?

当在外部函数中声明内部函数时,不仅定义了函数声明,而且还创建了一个闭包。该闭包不仅包含了函数的声明,还包含了在函数声明时该作用域中的所有变量。当最终执行内部函数时,尽管声明时的作用域已经消失了,但是通过闭包,仍然能够访问到原始作用域。

 

 

 

如上图所示,正如保护气泡一样,只要内部函数一直存在,内部函数的闭包就一直保存着该函数的作用域中的变量。

这就是闭包。闭包创建了被定义时的作用域内的变量和函数的安全气泡,因此函数获得了执行时所需要的内容。该气泡和函数本身一起包含了函数和变量。虽然这些结构不容易看见(没有包含这么多信息的闭包对象可以进行观察),存储和引用这些信息会直接影响性能。谨记每一个通过闭包访问变量的函数都具有一个作用域链,作用域链包含闭包的全部信息,这一点非常重要。因此,虽然闭包是非常有用的,但不能过度使用。使用闭包时,所有的信息都会存储到内存中,直到JavaScript引擎确保这心信息不再使用(可以安全地进行垃圾回收)或者页面卸载时,才会清理这些信息。

 

参考《JavaScript忍者秘籍》

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值