JavaScript函数执行讲解

96 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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版本规范中,对于一些词汇进行了修改

每一个执行上下文会关联到一个变量环境中
,在执行代码中变量和函数的声明会作为环境记录添加到变量环境中,参数也会被作为环境中。
对于函数来说,参数也会被作为环境记录到变量环境中。

作用域提升面试题

image.png

200

image.png

undefined

200

image.png

undefined

image.png

var a=100

b=100;

结果:100