持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
函数执行
函数执行过程
function foo()
{
console.log("foo")
}
foo()//打印foo
foo()
function foo()
{
console.log("foo")
}
//打印foo
函数与变量不一样,移到前面还是可以调用。这是为什么呢?
首先,会创建一个全局的对象,编译阶段
var GlobalObject = {
name:undefined
foo:0xa00 //会自动开辟一块空间来存储foo. 如下
}
foo的属性引用这这块空间
存储函数(foo)(0xa00)
[[scope]]:parent scope
函数的执行体(代码块)
编译后
AO(Activation Object) = {
name:"why"
foo:0xa00 //会自动开辟一块空间来存储foo. 如下
}
存储函数的空间放入ECStack调用,但是不是直接调用,而是在ECStack中创建一个函数执行上下文
函数执行上下文(EFC)
Fuctional Execution Context
VO():AO
开始执行函数代码
在VO里面找
一旦函数执行完,函数执行上下文会弹出ECStack,销毁。
变量查找规则
查找顺序:作用域链
什么叫沿着作用域链查找?
当前AO加上父级的GO
如果没找到会去找父级的VO+GO一直找下去。
var name="why"
foo(123)
fuction foo(num)
{
console.log(m)
var m=10
var n=20
function bar()
{
console.log(name)
}
bar()
}
变量环境和记录
GEC全局执行上下文
EFC函数执行上下文
早期的ECMA的版本规范:
每个执行上下文会被关联到一个变量对象,在源代码和函数声明会被作为属性添加到vo中
在最新的ECMA版本规范中,对于一些词汇进行了修改
每一个执行上下文会关联到一个变量环境中
,在执行代码中变量和函数的声明会作为环境记录添加到变量环境中,参数也会被作为环境中。
对于函数来说,参数也会被作为环境记录到变量环境中。
作用域提升面试题
200
undefined
200
undefined
var a=100
b=100;
结果:100