Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

全面的执行上下文与调用栈与块级作用域(写于 2021.6.7) #63

Open
lovelmh13 opened this issue Jun 7, 2021 · 0 comments

Comments

@lovelmh13
Copy link
Owner

lovelmh13 commented Jun 7, 2021

执行上下文和调用栈,涉及块级作用域

当我们需要执行一段代码:

console.log(foo)

var foo = 2
function foo () {
	return 1
}

console.log(foo)

输出:

function foo
2

这里我们跳过变量提升,就直接说这个当函数名和变量名相同的情况。

浏览器执行代码之前,都会进行一个编译的过程。也就是在这个过程中,产生了执行上下文和执行栈,这个我们后面说。

看一下编译的过程,当前代码会被编译为:

var foo = undefined
function foo () { return 1 }

console.log(foo)
foo = 2
console.log(foo)

函数声明的优先级比变量提升的优先级高,所以在 foo 被赋值为 2 之前,打印 foo 会返回 函数,当 foo 被赋值为 2 以后,就会打印出来 2 了。

执行上下文

showName()
console.log(myName)

var myName = '我的名字'
function showName () {
  console.log('你的名字')
}

当执行上面的代码时,浏览器先进行了编译,然后根据执行上下文和可以执行代码来执行出最后的结果:
image

执行完 addAll ,再次弹出栈定,只剩全局执行上下文

img

块级作用域与词法环境

在上面的执行上下文中,我们一直往变量环境里添加变量和函数,词法环境里空空如也。想让词法环境里装东西,就得先看一下块级作用域。

function foo(){
    var a = 1
    let b = 2
    {
      let b = 3
      var c = 4
      let d = 5
      console.log(a)
      console.log(b)
    }
    console.log(b) 
    console.log(c)
    console.log(d)
}   
foo()

刚执行 foo 时的执行上下文

image

可以看到 var 声明的变量在「变量环境」中,而 let声明的变量在「词法环境中」,且词法环境是一个栈结构。并且由于 var 没有块级作用域,所以在 {} 里的 c 也在编译阶段就出现在了 foo 的执行上线文中。

然后执行到 {} 代码块里时

image

代码块里的 b d 入词法环境栈,此时变量环境的 a 已经被置为 1,且块外的 b也被置为了 2。块内的变量并不会影响到块外的同名变量的值。

再继续执行,当执行到 console.log(a) 的时候,会从词法环境开始找起,自顶向下,如果找到了就返回它对应的值,如果没有到找,就再去变量环境里去找:

img

当作用域块执行完以后,属于作用域块内部定义的变量就会从词法环境弹出:

img

参考

极客时间 -> 浏览器与工作原理 -> 浏览器中的JavaScript执行机制

@lovelmh13 lovelmh13 changed the title 全面的执行上下文与执行栈与块级作用于(写于 2021.6.7) 全面的执行上下文与执行栈与块级作用域(写于 2021.6.7) Jun 7, 2021
@lovelmh13 lovelmh13 changed the title 全面的执行上下文与执行栈与块级作用域(写于 2021.6.7) 全面的执行上下文与调用栈与块级作用域(写于 2021.6.7) Jun 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant