您的位置:首页 > Web前端 > JavaScript

你不知道的JavaScript(二)变量提升

2017-07-11 18:27 288 查看

变量提升原理

看下面的简单例子:

console.log(a);
var a =2;


JavaScript会将上面的声明看成两个声明:
var a;
a=2;
。第一个定义声明在编译阶段进行,第二个赋值声明会被留在原地等待执行阶段。

第一个代码片段会以如下形式进行处理:

var a;
console.log(a);
a = 2;


这个过程就好像变量声明(函数声明也一样)从他们在代码中出现的位置被“移动”到了最上面,这个过程就叫作提升。

函数优先

函数声明和变量声明都会被提升,但是有一个值得注意的细节:函数首先会被提升,然后才是变量。

考虑下面的代码:

foo();
var foo;
function foo() {
console.log(1);
}
foo=function() {
console.log(2);
};


结果会输出1,而不是2。这个代码片段会被引擎理解为如下形式:

function foo() {
console.log(1);
}
foo();//1
foo=function() {
console.log(2);
}


尽管
var foo
出现在
function foo()
的声明之前,但它是重复的声明,因此被忽略,因为函数的声明会被提升到普通变量之前。

虽然重复的var声明会被忽略掉,但是出现在后面的函数声明能够覆盖之前的声明:

foo();//3
function foo() {
console.log(1);
}
var foo=function() {
console.log(2);
}
function foo() {
console.log(3);
}


以上这些内容虽然听起来没有太大用处,但是它说明了在同一个作用域中进行重复定义非常糟糕的,而且经常会导致各种奇怪的问题。

一个普通快内部的函数声明通常会被提升到所在作用域的顶部,这个过程并不会像下面的代码暗示的那样可以被条件判断所控制:

foo();
var a=true;
if(a) {
function foo() { console.log('a'); }
}
else {
function foo() { console.log('b') }
}


上述代码会被理解为如下形式:

function foo() {console.log('b')};
var a;
foo();
a=true;
if(a) {}
else{}


所以这个行为并不可靠,应该尽可能避免在块内部声明函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息