第一步:
函数被调用
第二步:
执行引擎创建一个函数执行上下文环境。执行上下文环境包括变量对象,作用域链,this指针三部分。
在这里为了说明问题,我们只关心变量对象。
在函数执行上下文中,变量对象是不能直接访问的
变量对象包含普通参数(formal parameters) 与特殊参数(Arguments)对象(具有索引属性的参数映射表)。
特殊参数(Arguments)对象是通过函数的arguments属性初始化的。即arguments属性的值是Arguments对象。
创建变量对象的过程是这样:
1.建立特殊参数(Arguments)对象:属性名是'0'、'1'、'2'.....,属性值就是函数调用时传入的实参。此外arguments.length是实际参数的个数。此时函数的形参在函数中作为局部变量存在,且与arguments中的数据共享状态(这句话极为重要!)
2.函数提升:找到这个将要执行的函数内的所有函数声明,储存在变量对象中,属性名就是函数名,属性值就是函数的引用(所在的内存地址)。如果有多个同名的函数声明,后出现的函数覆盖前面的属性值。
3.变量提升:找到这个将要执行的函数内的所有变量声明,储存在变量对象中,属性名就是变量名,属性值是undefined。
第三步:
先掌握一个概念:活动对象(activation object)
活动对象其实和变量对象是同一个东西在不同时期的两种叫法。函数还未开始执行(创建上下文的期间)时叫变量对象,函数开始执行以后就叫活动对象。
开始顺序执行函数体内的同步函数语句,此时变量对象切换为活动对象
形参赋值和函数声明赋值在第二步已经完成了。只剩下给第二步中的普通参数中声明过的变量进行赋值,即把undefined替换为真实值。
第四步:
函数执行完销毁(没有闭包情况下)