在栈中进进出出JavaScript

本文只起到一个提纲挈领的作用

一、编译和执行

JavaScript代码是先编译后执行的

① 编译

编译生成执行上下文和可执行代码。

执行上下文

  • 变量环境

    • var声明的变量,值为undefined(变量提升)
    • 函数(把函数整体代码拿过来)
  • 词法环境(维护了一个小型的栈结构)

    • let和const声明的变量
    • 块级作用域中的let与const
  • outer

    • 指向全局上下文
  • this

可执行代码

  • 函数调用
  • 赋值操作
  • ……

② 执行

  • 按照可执行代码的顺序先后执行

二、JavaScript调用栈

JavaScript执行的时候会编译产生全局执行上下文,并把他压入栈底。调用一个函数的时候产生一个函数执行上下文入栈。

① 全局执行上下文

② 函数执行上下文

三、作用域

① ES6之前只有全局作用域和函数作用域。

② let和const产生块级作用域

③ 块级作用域的变量查找的机制

  • 块级作用域可以访问外部,而外部无法访问块级作用域内部

④ 词法作用域

  • 词法作用域是编译的时候就决定好的,和函数是怎么调用的没有关系。

四、作用域链和闭包

① 函数的作用域链

  • 函数通过outer指向全局作用域,如果当前函数作用域中没有查找到变量,则到全局作用域中去找,全局作用域中还找不到就报错。

② 闭包

  • 闭包依赖于词法作用域规则,是编译的时候就决定好的。
  • 有了闭包,函数执行的时候如果在当前函数上下文找不到该变量,则先去闭包中找,再通过outer去全局上下文中寻找

六、this

① 全局执行上下文中的 this

  • node是global
  • 浏览器是window

② 函数执行上下文中的 this

  • 默认是全局执行上下文中的全局对象

③ 对象中的this

  • 直接通过该对象调用对象方法时this就是该对象
  • 赋值操作完之后再调用则具体分析

④ 如何设置this

  • bind

    • 只改变this指向却没有调用
  • apply

    • 改变this指向后立即调用,参数是数组的形式
  • call

    • 改变this指向后立即调用,参数要一个个传
  • 通过构造函数中设置

⑤ this 不会从外层函数中继承

  • 只要在函数里面的this就指向全局,和他所在的环境无关

⑥ 箭头函数中的this

  • 箭头函数中的this依赖于它所在的环境

你可能感兴趣的:(浏览器工作原理,前端,javascript)