javascript的变量提升和作用域

先来一个例子来洗洗脑:

1
2
3
4
5
6
7
8
var a=1;
function foo(){
if(!a){
var a=10;
}
alert(a);
}
foo();

想来大家应该知道答案:输出‘10’,那为什么会这样呢,稍微学习过js的应该知道其原理。js的变量声明的机制跟java,c++,c等程序语言有些差别(这几个语言含有块级作用域(block-level scope))。

在js编译机制执行下的代码执行顺序:

1
2
3
4
5
6
7
8
9
10
11
//函数声明
function foo(){
var a;
if(!a){
a=10;
}
alert(a);
}
var a;//变量声明
a=1;
foo();

在解释这个编译过程中,涉及了函数的声明优先级高于变量的声明,js的函数作用域。

  1. 函数的声明优先级高于变量的声明:

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    foo();
    var foo;
    function foo(){
    console.log(1);
    }
    foo = function(){
    console.log(2);
    }

    输出的结果:1;

    原因就在于函数的声明优先级高于变量的声明。

    在js编译机制执行下的代码执行顺序:

    1
    2
    3
    4
    5
    6
    7
    8
    function foo(){
    console.log(1);
    }
    foo();
    var foo;
    foo = function(){
    console.log(2);
    }

  2. js的函数作用域:

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function foo() {
    var x = 1;
    if (x) {
    (function () {
    var x = 2;
    console.log(x)//2
    }());
    }
    console.log(x);// x is still 1.
    }

    倘若没有添加一个立即执行函数,就不会构造一个类似的函数作用域。那么在if块外面中就不会打印输出依旧是1;

最后小结:

​ 只有声明本身会被提升,而其他的操作在原来的位置按照代码的顺序执行。变量和函数声明都会提升,在变量重复声明时,在后面的声明会覆盖前面的声明。(特别注意的是:函数变量的声明会在普通变量声明的前面声明)


本文由 Abert 创作,采用 知识共享署名 4.0 国际许可协议。

本站文章除注明转载/出处外,均为本站原创或翻译,转载请务必署名。