Variable Hosting 变量提升

为什么要讲变量提升,首先看一个小测试,如果你答错了,那就说明你需要了解一下变量提升的机制

0 测试

看看下面分别输出多少?

console.log(x); // -> ?
var x = 5;
console.log(x); // -> ?
console.log(y); // -> ?

答案是:

第二个log为5,可以理解,第一个undefined也可以理解,为什么最后的y是error呢?

因为Javascript engine 在运行代码前,会重新调整代码的结构,提升了变量x的声明,上面的代码在运行前结构大体变成了这样

var x;
console.log(x); // -> undefined
x = 5;
console.log(x); // -> 5
console.log(y); // -> Uncaught ReferenceError: y is not defined

1 变量提升

只有变量声明如var = x会被提升的代码的顶部,变量的赋值如var x = 10不会被提升;

没有使用变量声明关键字如var,let, const等的变量声明也不会被提升

console.log(x);
console.log(y);

var x = 'This will log "undefined"!';
y = 'This will throw an error :(';

2 函数提升

函数提升有点不同,有两种定义函数的方式:函数表达式和函数声明

函数表达式: 类似变量提升,fn被提升到代码顶部,并且值为undefined,之后fn被赋值函数

var fn = function() {
    // do something...
}

函数声明:  整个代码块都会被提升,变量fn就是函数本身,会被提升到最顶部,甚至在变量声明之前

function fn() {
    // do something...
}

示例:

fnDeclaration(); // -> This works!
fnExpression(); // -> Uncaught TypeError: fnExpression is not a function

function fnDeclaration() {
    console.log('This works!');
}

var fnExpression = function() {
    console.log("This won't work :(");
}

3 示例

变量提升前的代码

var a = 123;
var b = 'abc';

var fnExpression = function() {
    var c = 456;
    var d = 'def';
}

function fnDeclaration() {
    var e = 789;
}

变量提升后的代码

function fnDeclaration() {
    var e;
  
    e = 789;
}

var a;
var b;
var fnExpression;

a = 123;
b = 'abc';

fnExpression = function() {
    var c;
    var d;
  
    c = 456;
    d = 'def';
}

总结:

先声明总是对的,函数提升有点意思,函数表达式和变量声明很像,函数声明才最靠前

参考资料:《Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript

猜你喜欢

转载自my.oschina.net/u/2510955/blog/1580802