美文网首页
深入理解JS之Scope链

深入理解JS之Scope链

作者: Doter | 来源:发表于2020-03-21 18:40 被阅读0次

作用域的创建

作用域的创建时机

解析器在解析的过程中在生成AST的时候,同时构建其作用域。

查看其作用域链

如下代码:在控制台直接执行

var testSelf = {};
function A(){
  var a = "1";
  var b = testSelf;
  var c = "3";
  function B(){//闭包1
    var c = "1"
    function C(){//闭包2
      var d = "1"
      console.log(a,b,c,d)
    }
    debugger;
    C()
  }
  debugger;
  return B
}
debugger
var B = A()
B()
testSelf.a="aaa";
B()
A的scope链 B的scope链 C的scope链g

根据上图即代码我们可以得到一下结论:

  1. 方法的Scope链在该方法创建后以及生成了[[scopes]],而这个scopes是数组形式的链式。
  2. 当个方法的内部使用的变量未在该方法中声明。则会在其创建的时所在的scope中查找,如果找到了,就将该scope加入[[scopes]],并值将该变量加入scope。
  3. 当上层scope没有找到,则依次向上查找并重复步骤2。
  4. 子scopes共享父的scopes

123比较容易理解,关于4.
我们观察B:
在B中并没有使用到变量ab,
如同C中没有使用变量e,
但是C中使用了a和b,根据123,将会在C的scopes中加入A的作用域里的a和b。
但是我们发现B的scopes中也有A的作用域里的a和b。
所以我觉得可以理解为,B的scopes是C的父scopes,当在解析C的时候,发现a和b变量不存在,则将会在scopes中添加Closure(闭包)A。从而B也会有Closure(闭包)A。

小结:
scope链生成是在代码解析的时候生成的,解析器通过识别到使用的变量未在该方法中声明,则会在该方法的声明创建的地方的作用域查找,依次向上直到全局scope。

同时scope中存储的数据是可修改的,具体参考demojs打印结果。

附加题

var x = 10
function fn() {
  console.log(x)
}
function show(f) {
  var x = 20;
  (function() {
    f() 
  })()
}
show(fn)

我们尝试解答这个题:
首先回顾,闭包是在js解析的时候生成的。

  1. 当解析器解析fn的时候,发现console.log(x)里面的x没有在fn中定义。
  2. 那么将会在fn声明所在的scope(即全局scope)中查找x,当找到x后,将添加到的scopes里面,且x的值为10。
  3. 接下来show将fn作为参数传递进去了。
  4. 尽管show内部声明了x,并且有个闭包的匿名函数,但是f执行时,这个f在解析过程中已经形成了闭包,即第2步。那么执行时,直接在Scopes中找到了x的值为10。随即打印了10

延深思考:如果我删除var x = 10。执行会出现什么结果?

推荐scope的文章

相关文章

  • 深入理解JS之Scope链

    作用域的创建 解析器在解析的过程中在生成AST的时候,同时构建其作用域。 查看其作用域链 如下代码:在控制台直接执...

  • 【前端推荐第11天】作用域链

    今日推荐文章:《深入理解JavaScript系列:作用域链(Scope Chain)》 原文作者:汤姆大叔, 来源...

  • 深入理解vue中的slot与slot-scope

    深入理解vue中的slot与slot-scope

  • JS博客

    JS构造函数及new运算符 JS原型对象和原型链 函数作用域和作用域链 干货分享:让你分分钟学会JS闭包 深入理解...

  • 作用域链简介

    每一段js代码(全局代码或函数)都有一个与之关联的作用域链(scope chain)。 这个作用域链是一个对象列表...

  • 2018-01-09 关于javascript原型链的思考 pl

    s 深入理解原型和原型链? 构造函数 理解原型和原型链 new的时候js都干了什么? 一个实现继承的demo 构造...

  • 深入理解JS原型链

    前文: 继承是OO(面向对象)语言中的一个最为人津津乐道的概念。许多OO语言都支持两种继承方式:接口继承和实现继承...

  • 作用域/作用域链 闭包及其使用

    一、作用域、作用域链 作用域(scope) 浅显的理解: 作用域就是变量的可用范围(scope) 为什么要有作用域...

  • __proto__ 和 prototype ➡️ 原型链继承

    参考文章: 从proto和prototype来深入理解JS对象和原型链 写在前面的自己的理解: 每个函数都有自己的...

  • 深入理解JS 中原型和原型链

    JS 中原型和原型链深入理解 首先要搞明白几个概念: 函数(function) 函数对象(function obj...

网友评论

      本文标题:深入理解JS之Scope链

      本文链接:https://www.haomeiwen.com/subject/dqzyyhtx.html