变量对象
变量对象 Variable Object
函数变量对象的创建过程
- 建立
arguments
对象:检查当前上下文的函数参数,建立该对象下的属性和属性值。 - 检查当前上下文的函数声明,指的是
function
关键字声明的函数,在变量对象中以函数名建立一个属性,属性值为指向该函数的所在内存地址的引用。 - 检查当前上下文中的变量声明,在变量对象中以变量名建立一个属性,属性值为
undefined
。
如果变量与函数同名,则在这个阶段,以函数值为准
1 | console.log(foo); // function foo |
函数参数与变量同名,参数为准
1 | function foo(a){ |
函数参数与内部函数同名,内部函数为准
1 | function foo(a){ |
具体过程
1 | function test() { |
创建
未进入执行阶段之前,变量对象中的属性都不能访问!但是进入执行阶段之后,变量对象转变为了活动对象,里面的属性都能被访问了,然后开始进行执行阶段的操作。执行阶段
AO:活动对象
实际执行过程1
2
3
4
5
6
7
8
9
10
11function test() {
function foo() {
return 2;
}
var a;
console.log(a);
console.log(foo());
a = 1;
}
test();
全局上下文变量对象
浏览器,全局对象为Window
。
1 | windowEC={ |
变量对象和this
都指向Window
对象
全局上下文的生命周期,与程序的生命周期一致,只要程序运行不结束,比如关掉浏览器窗口,全局上下文就会一直存在。其他所有的上下文环境,都能直接访问全局上下文的属性。
let/const
let/const
声明的变量,是否还会变量提升?let/const
声明的变量,仍然会提前被收集到变量对象中,但和var
不同的是,let/const
定义的变量,不会在这个时候给他赋值undefined
。
因为存在暂时性死区,所以不能再声明前使用。
变量提升
编译时和运行时
- 编译时:var 和 function 声明的变量和函数提升
- 运行时:变量初始化
什么是变量提升
将变量声明及函数声明提升至当前作用域的顶端。
为什么会存在变量提升
提升存在的根本原因就是为了解决函数间互相调用的情况
- var 声明的提升
只提升声明,未赋值前使用是undefined
var 声明的变量只存在全局作用域和函数作用域
例一
1 | console.log(a); |
预编译
1 | var a; |
例二
如果当前作用域声明了多个同名变量,同一个标识符会被提升到顶部,赋值操作顺序执行。
1 | var a = 10 |
预编译
1 | var a |
函数声明提升
- 如果函数声明方式跟变量声明方式一样,则提升方式也是一样的
1
2
3
4
5console.log(fun);//undefined
var fun=function(){
console.log(1);
}
fun();//1- 使用
function
声明
会把声明和赋值全部提升到作用域顶部
1
2
3
4fun();//1
function fun(){
console.log(1);
}
例三
1 | function test(arg) { |
阿里面试题
考点:变量提升,作用域,继承
1 | function Foo() { |