美文网首页
从执行上下文看闭包

从执行上下文看闭包

作者: js好难学啊 | 来源:发表于2018-12-12 23:37 被阅读0次

闭包

定义

闭包是引用了自由变量的函数。

自由变量的定义

自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。

举个例子

直接上代码

var data = []
for (var i = 0; i < 3; i++) {
  data[i] = function() {
    console.log(i)  
  }
}

data[0]()
data[1]()
data[2]()

从执行上下的角度来解读这几行代码如下:

  1. 全局上下文(globalContext)创建并入栈
  2. 创建全局上下问的AO对象
globalContext.AO = {
  ...otherData,
  data: undefined
  i: undefined
}
// 确定完之后,会将AO添加到作用域链的前端
globalContext = {
  AO: 同上,
  scopeChain: [AO]
}
  1. 执行代码赋值i = 0,就是说globalContext中AO的i也变成了0,碰到data[0]函数的创建,函数创建阶段会确定该函数的[[scope]]属性,此时data[0].[[scope]] = globalContext.scopeChain
  2. 那当代码执行到i = 1时也是同理globalContext中AO的i也变成了1,此时data[0].[[scope]]中的i其实也就已经变成了1,因为他们都是指向globalContext中AO的i
  3. i=2不再赘述
  4. data[0]函数即将执行,进入激活阶段,首先创建data[0]的执行上下文并入栈。
  5. 然后拷贝一份它的[[scope]]属性到作用域链
data[0].context = {
  scopeChain: [data[0].[[scope]]]
}
  1. 确定它的AO对象并放置于作用域链的前端,以及确定this指向
data[0].context = {
  AO: {
    arguments: {length: 0}
  },
  scopeChain: [AO, data[0].[[scope]]],
  this
}
  1. data[0]进入执行阶段当要打印i的时候,自身的AO对象中并没有,怎么办?去作用域链找!它的作用域链是本身的AO本身的[[scope]]对象组成。本身的[[scope]]对象中包含了globalContext.AO对吧。 所以最终会在globalContext.AO中找到i,所以输出了3
  2. 在data[0]执行完毕后会出栈,data[1]又会重复上述步骤6~9。最终的结果是3个3.

如何产生我们期望的结果呢?

终于要出场了!那就是今天的主角闭包

var data = []
for (var i = 0; i < 3; i++) {
  data[i] = (function (i) {
    return function() {
      console.log(i)
    }
  })(i)
}

data[0]()
data[1]()
data[2]()
(function () {})() //这样的代码形式是个闭包,也称为自执行函数

这个代码在执行期间与之前不同的地方在于它会多创建一个闭包的执行上下文,在闭包的执行上下文中,保存了本次i的数据,并且代码中没有其他因素会干扰这个值。
当执行到data[0]这个函数时,它的执行上下文的作用域链其实为

context = {
  AO: {arguments: {length: 0}},
  scopeChain: {
    this.AO,
    anonymousContext.AO, // 这个AO = {arguments: {0: 0, length: 1}, i: 0}
    globalContext.AO // 这个AO = {...otherData, data: [...], i: 3}
  }
}

所以当打印i的时候,本身的AO中还是没有,所以去去作用域链中查找,在闭包的作用域链中就已经查到了i,所以就结束了,不会继续查找globalContext中的i

相关文章

  • 3-1 作用域和闭包 执行上下文

    3-1 作用域和闭包 执行上下文 知识点 执行上下文 this 作用域 作用域链 闭包 执行上下文 先执行后定义

  • 从执行上下文看闭包

    闭包 定义 闭包是引用了自由变量的函数。 自由变量的定义 自由变量是指在函数中使用的,但既不是函数参数也不是函数的...

  • 面试题 闭包 继承 原型

    闭包 什么是闭包?闭包的作用?闭包的应用?答: 函数执行,形成私有的执行上下文,使内部私有变量不受外界干扰,起到保...

  • 初(粗)谈闭包

    闭包 1 .闭包是一个特殊对象,它由执行上下文(代号A)与在该执行上下文中创建的函数(代号B)共同组成。当B执行时...

  • 执行上下文,词法作用域,作用域链,闭包

    执行上下文,词法作用域,作用域链,闭包

  • JavaScript闭包学习笔记

    @(JS技巧)[闭包] JavaScript闭包学习笔记 什么是闭包? 有些情况下,函数调用完成之后,其执行上下文...

  • 2020年前端面试复习必读文章

    1. JavaScript 基础 1.1 执行上下文/作用域链/闭包 理解 JavaScript 中的执行上下文和...

  • JS执行上下文

    我们在学习作用域或者闭包时,总是绕不开执行上下文,执行栈等术语,那到底什么是执行上下文呢? 一、什么是执行上下文 ...

  • 深入理解闭包(四)——执行上下文栈

    原文地址:深入理解闭包(四)——执行上下文栈 执行上下文可以理解为当前代码的执行环境,JavaScript中的运行...

  • js 随笔

    js 执行机制: js执行上下文: 只有理解了js 执行上下文才能更好的理解 js变量提升以及 作用域和闭包 所谓...

网友评论

      本文标题:从执行上下文看闭包

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