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

JS学习笔记:变量提升

2016-07-17 16:57 543 查看

变量提升规则:

1.变量声明会提升至作用域顶部,但赋值不会。

// 我们知道这样不能正常工作(假设这里没有名为 notDefined 的全局变量)
function example() {
console.log(notDefined); // => throws a ReferenceError
}

// 但由于变量声明提升的原因,在一个变量引用后再创建它的变量声明将可以正常工作。
// 注:变量赋值为 `true` 不会提升。
function example() {
console.log(declaredButNotAssigned); // => undefined
var declaredButNotAssigned = true;
}

// 解释器会把变量声明提升到作用域顶部,意味着我们的例子将被重写成:
function example() {
var declaredButNotAssigned;
console.log(declaredButNotAssigned); // => undefined
declaredButNotAssigned = true;
}


2.匿名函数表达式会提升它们的变量名,但不会提升函数的赋值

function example() {
console.log(anonymous); // => undefined

anonymous(); // => TypeError anonymous is not a function

var anonymous = function () {
console.log('anonymous function expression');
};
}


3.命名函数表达式会提升变量名,但不会提升函数名或函数体

function example() {
console.log(named); // => undefined

named(); // => TypeError named is not a function

superPower(); // => ReferenceError superPower is not defined

var named = function superPower() {
console.log('Flying');
};
}

// 当函数名跟变量名一样时,表现也是如此。
function example() {
console.log(named); // => undefined

named(); // => TypeError named is not a function

var named = function named() {
console.log('named');
}
}


4.函数声明提升它们的名字和函数体

function example() {
superPower(); // => Flying

function superPower() {
console.log('Flying');
}
}


例子:

JavaScript 会提升变量声明。这意味着 var 表达式和 function 声明都将会被提升到当前作用域的顶部。

bar();
var bar = function() {};
var someValue = 42;

test();
function test(data) {
if (false) {
goo = 1;

} else {
var goo = 2;
}
for(var i = 0; i < 100; i++) {
var e = data[i];
}
}


上面代码在运行之前将会被转化。JavaScript 将会把 var 表达式和 function 声明提升到当前作用域的顶部。

// var 表达式被移动到这里
var bar, someValue; // 缺省值是 'undefined'

// 函数声明也会提升
function test(data) {
var goo, i, e; // 没有块级作用域,这些变量被移动到函数顶部
if (false) {
goo = 1;

} else {
goo = 2;
}
for(i = 0; i < 100; i++) {
e = data[i];
}
}

bar(); // 出错:TypeError,因为 bar 依然是 'undefined'
someValue = 42; // 赋值语句不会被提升规则(hoisting)影响
bar = function() {};

test();


没有块级作用域不仅导致 var 表达式被从循环内移到外部,而且使一些 if 表达式更难看懂。

如果没有提升规则(hoisting)的知识,下面的代码看起来会抛出异常 ReferenceError。

// 检查 SomeImportantThing 是否已经被初始化
if (!SomeImportantThing) {
var SomeImportantThing = {};
}


实际上,上面的代码正常运行,因为 var 表达式会被提升到全局作用域的顶部。

var SomeImportantThing;

// 其它一些代码,可能会初始化 SomeImportantThing,也可能不会

// 检查是否已经被初始化
if (!SomeImportantThing) {
SomeImportantThing = {};
}


注意,是提升到当前作用域的顶端:

// 来自 Nettuts+ 的一段代码,生动的阐述了 JavaScript 中变量声明提升规则
var myvar = 'my value';

(function() {
alert(myvar); // undefined
var myvar = 'local value';
})();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript