在JS代码执行前,先对VAR变量进行声明&对FUNCTION函数进行声明和定义,这个过程称为变量提升
var a = 0;
声明让变量赋值为undefined,即 var a;
声明定义让该函数名指向存储该函数内部代码片段的地址,而代码片段仅作为片段存储在堆空间里
同样的,在调用一个函数,即执行一个函数时,也会先进行变量提升
在JS执行开始时,除了普通代码正常执行(a= 0)外,会直接跳过函数,因为已进行了声明和定义
全局变量和Window全局对象中属性的“映射机制”
window.document.getElementById() = document.getElementById();
window.setInterval() = setInterval();
变量提升阶段,在全局作用域下不仅会对VAR的变量进行声明,同时会给window全局对象设置一个与变量名相同的属性值(私有作用域中的私有变量和window无关)
在变量未被赋值前,变量和window.变量 的值都为undefined
然而,undefined分为两种情况:
- window存在该变量属性,值等于undefined
- window根本不存在该变量属性
由上述描述可知,是第一种情况(‘变量’ in window 可用于检测某个属性值手否隶属于这个对象,返回值为true或false)
当变量或者window属性值变化时,另一个也会跟着变化,这就全局变量和window中属性存在的“映射机制”
特例:
console.log(a);
console.log(window.a);
console.log(‘a’ in window);
a= 12;
console.log(a);
console.log(window.a);
- 第1行输出直接报错:Uncaught ReferenceError:a is not define
- 此时浏览器先看是否存在a变量,发现不存在,再查看window是否存在该属性,发现依旧不存在,因此报错
- 注释掉第1行,第2行输出为undefined,因为当前全局对象中不存在a属性 第3行,输出为false,验证上一行所说
- 第4行,等价于window.a = 12,也就是说,它是前者的简写,也就是说,这里是给全局对象window的属性a赋值12
- 第5行输出为12,但是该a并不是变量,依旧是全局对象的属性 第6行输出为自然也为12
注意:
var a = 12, b = 12; // a 和 b都带var
var a = b = 12;// a 带var ,b不带var
私有作用域的变量提升例子
console.log(a,b);
var a = 12,b = 12;
function(){
console.log(a,b