变量提升
var定义的内容会导致变量提升(同一作用域内,无论使用var定义在哪里的内容,都会在最前面提前声明,在原定义的地方赋值,且变量提升不会受if影响,这是在预编译时发生的时,和执行时无关),如果在全局中使用var,则会被设置在window上;函数同样存在变量提升,且优先级大于var定义的同名内容(函数>arguments>var变量)
var name = 'erdong';
(function () {
if (typeof name === 'undefined') { // 此时name为undefined
var name = 'chen'; // 变量提升,在自执行函数最前面声明了name
console.log(name); // 执行输出
} else {
console.log(name);
}
})();var a = 10;
function test() {
a = 100; // 变量提升,所以赋值test方法内声明的a
console.log(a); // 输出test中的a
console.log(this.a); // 输出test执行地方的a
var a; // 新定义a变量,变量提升
console.log(a); // 输出test中的a
}
test(); if (!('a' in window)) {
var a = 1; // 变量提升,到全局作用域window;var声明在全局上会被声明到window上
}
console.log(a); // 输出undefined var c = 1; // 覆盖c方法
function c(c) { //变量提升到最前面
console.log(c);
var c = 3;
}
console.log(c); //输出1
c(2); // 报错 c is not a functionconsole.log(c); // c方法
var c; // 变量提升,移动到最前面声明
function c(a) {
console.log(a); // 输出a方法
var a = 3; // 定义了新变量a,变量提升到方法c的最前面声明
function a(){ // 变量提升优先于变量a
}
}
c(2); // 输出a方法(function() {
var a = b = 3; // a在自执行函数内声明,b未声明,所以变量提升到全局作用域
})();
console.log(typeof a === 'undefined'); // a为函数私有,所以使用会报错,typeof对报错内容执行会返回undefined,所以输出true
console.log(typeof b === 'undefined'); // b为全局内容,在函数内被赋值为3,所以输出falseconsole.log(typeof a); // 输出function
function a() {} // 变量提升
var a; // 已存在a,无操作
console.log(typeof a); // 输出functionvar x = 1;
if(function f(){}){ // 判断条件会被转Boolean类型,不存在变量提升
x += typeof f;
}
console.log(x); // 输出1undefined总结
- 变量提升属于预编译范畴,只要使用var定义了,在同一作用域(全局或函数作用域)内就会被提示(如没有执行到的if内部,如果其内部存在var,则仍会被提示)
- 变量提升存在先后顺序,
function>agruments>var,优先级以及定义位置越靠前,则提升 - function和var提升的差别在于,function是整体提升(名称以及函数自身,相当于提升加赋值),var只是定义提升(提升后值为undefined,在原本定义处再进行赋值)
- 对于未定义过的变量赋值,会将其在外层作用域进行变量提升
