最近学习了一下v8在编译js时做的事情,终于摸清楚为什么下面代码中 a会报错 b会返回10了。
function sa(){
var a = b = 10
}
sa()
console.log(a)
console.log(b)
v8在执行js时会创建一个全局执行上下文栈 esc
为了保证全局代码能够正常执行,然后还会创建一个全局执行上下文栈gec
全局执行上下文栈有一个对象叫variable Object 这玩意简称vo
vo指向GlobalObject 也就是window 简称go
全局执行上下文栈扫描代码的时候会把基础类型的变量添加到window中(var声明的变量),把函数开辟一块内存存进去,同时存入的还有他的外部作用域,然后函数名为变量指向内存的地址,然后代码开始从上至下执行,变量依次赋值。这就是为什么函数提升比var声明的变量提升大的原因。
当函数执行时,会创建一个临时的函数执行上下文,创建vo指向ao,这个函数执行上下文在函数执行结束后一般会销毁。
函数执行上下文的工作原理和vo一致,都是扫描代码,生成变量,从上至下执行…
函数执行上下文如果遇到一个变量,首先会在自己的vo中查找,如果找不到,会在生成时存入的外部作用域中查找
var a = 10
funciton b(){
console.log(a)
}
如上代码会输出10
如果函数执行上下文中给某个没有声明过的变量赋值,则会直接在外部vo中生成
function a (){
a = 10
}
a() //a = 10 a中的赋值会替换调函数a
而var a = b = 10 会被分解为 var a = 10 b = 10 虽然不建议这么写,但是js的语法是相对自由的,他不会报错,而是执行,所以 函数a会报错,b会被函数sa创建到全局中。