资讯专栏INFORMATION COLUMN

彻底理解JavaScript中的Closure

chuyao / 329人阅读

摘要:的本质问题其实就是词法作用域的问题或者说是引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找引擎查找标识符位置的规则简而言之就是作用域查找会在找到第一个匹配的标识符时停止换句话说是作用域查找始终从运行时所处的最内部作用域开始

Closure的本质问题其实就是词法作用域的问题, 或者说是JavaScript引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找.

JavaScript引擎查找标识符位置的规则, 简而言之, 就是:

作用域查找会在找到第一个匹配的标识符时停止

换句话说是: 作用域查找始终从运行时所处的最内部作用域开始, 逐级向外或者说向上进行, 知道遇见第一个匹配的标识符为止

带着以上的结论, 我们看看这个例子来验证一下:

function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}

//Question 1
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);

//Question 2
var b = fun(0).fun(1).fun(2).fun(3);

//Question 3
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);

Question 1的答案和解释

var a = fun(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0

Question 1.1
传入n=0,并没有传入o, 所以是undefined。这个时候a是含有fun的object:

{
    fun:function(m){
      return fun(m,n);
    }
}

Question 1.2
a包含的fun被trigger了, 传入了n=1并且最终trigger了fun(m, n).
那么问题来了, m和n分别是什么?
m是刚刚传进来的1, 这个很简单;
n只能根据作用域网上查找, 发现时上次传进来的一个形参, 它的值就应该是上次传进来的0;
所以, 最终a.fun(1)是trigger了fun(1, 0), 最后的答案是0.

对于Question 1.3和1.4来说, 同理最终的答案也是0.

Question 2的答案和解释

b = fun(0).fun(1).fun(2).fun(3)
//undefined
//0
//1
//2

根据Question 1.2的解释 就很好理解这个答案了

Question 3的答案和解释

var c = fun(0).fun(1); c.fun(2); c.fun(3);
//undefined
//0
//1
//1

根据Question 1.2的解释 var c = fun(0).fun(1)会分别log出undefined0
这个时候c应该是含有fun的object:

{
    fun:function(m){
      return fun(m,n);
    }
}

当c.fun(2)的时候 其实也是trigger了fun(m, n).
m是当前传入的2. n由于没有被传入, 只能向外作用域寻找, 发现上次传入的n且n=1.
所以最后log的值为1.

同理对于c.fun(3) 最后log的值也为1.

总结
通过理解JavaScript引擎向上查找作用域的规则 可以更好的让我们理解Closure

Reference:
你不一定能做对的JavaScript闭包面试题
You Don"t Know JS: Scope & Closures

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88418.html

相关文章

  • javascript对象不完全探索记录01:this! which?

    温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命 这一切,源于阮大神博文学习Javascript闭包(Closure)- 阮一峰中的一道思考题 //问题1: var name = The Window; var object = {   name : My Object,   getNameFunc : function(){     return function(){    ...

    rubyshen 评论0 收藏0
  • 谈谈我所理解的闭包,js、php、golang里的closure

    摘要:当初看这个解释有点懵逼,理解成闭包就是函数中的函数了。里的闭包最近不满足于只干前端的活,开始用起了。里的闭包最近在学习语言,让我们来看一下语言里的闭包。在中,闭包特指将函数作为值返回的情况,被返回的函数引用了生成它的母函数中的变量。 本人开始接触编程是从js开始的,当时网上很多人说闭包是难点,各种地方对闭包的解释也是千奇百怪。如今开始接触js以外的各种编程语言,发现不光是js,php、...

    betacat 评论0 收藏0
  • 谈谈我所理解的闭包,js、php、golang里的closure

    摘要:当初看这个解释有点懵逼,理解成闭包就是函数中的函数了。里的闭包最近不满足于只干前端的活,开始用起了。里的闭包最近在学习语言,让我们来看一下语言里的闭包。在中,闭包特指将函数作为值返回的情况,被返回的函数引用了生成它的母函数中的变量。 本人开始接触编程是从js开始的,当时网上很多人说闭包是难点,各种地方对闭包的解释也是千奇百怪。如今开始接触js以外的各种编程语言,发现不光是js,php、...

    zhoutao 评论0 收藏0
  • 通过示例学习JavaScript闭包

    摘要:译者按在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包,这篇博客将提供一些代码示例,帮助大家理解闭包。然而,如果通过代码示例去理解闭包,则简单很多。不过,将闭包简单地看做局部变量,理解起来会更加简单。 - 译者按: 在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包(Closure),这篇博客将提供一些代码示例,帮助大家理解闭包。 原文: JavaScript Clos...

    xingpingz 评论0 收藏0
  • 理解Javascript的闭包

    摘要:但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。可惜的是,并没有提供相关的成员和方法来访问闭包中的局部变量。 (收藏自 技术狂) 前言:还是一篇入门文章。Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将...

    dayday_up 评论0 收藏0

发表评论

0条评论

chuyao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<