zoukankan      html  css  js  c++  java
  • javascript中变量提升的理解

    网上找了两个经典的例子

    var foo = 1;
    function bar() {
        if (!foo) {
            var foo = 10;
        }
        alert(foo);
    }
    bar();  // 10
    
    
    var a = 1;
    function b() {
        a = 10;
        return;
        function a() {}
    }
    b();
    alert(a);// 1
    

    在JavaScript中,函数、变量的声明都会被提升(hoisting)到该函数或变量所在的scope的顶部。即——JavaScript的变量提升。

    javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:

    • 语言内置:所有的作用域中都有 this 和 arguments 关键字;
    • 形式参数:函数的参数在函数作用域中都是有效的;
    • 函数声明:形如function foo() {};
    • 变量声明:形如var bar;

    名字声明的优先级如上所示。也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。

    (function(){
        var foo;
        console.log(typeof foo);  //function
         
        function foo(){}
     
        foo = "foo";
        console.log(typeof foo);  //string
        
        var foo;
    })();
    
    function test() {
        foo();             // TypeError "foo is not a function"
        bar();             // "this will run!"
        var foo = function () { // function expression assigned to local variable 'foo'
            alert("this won't run!");
        }
        function bar() {   // function declaration, given the name 'bar'
            alert("this will run!");
        }
    }
    test();
    
    

    变量的提升(Hoisting)只是其定义提升,而变量的赋值并不会提升
    再来看一个例子,下面两段代码其实是等价的:

    function foo() {
        if (false) {
            var x = 1;
        }
        return;
        var y = 1;
    }
    function foo() {
        var x, y;
        if (false) {
            x = 1;
        }
        return;
        y = 1;
    }
    

    创建一个函数的方法有两种:
    一种是通过函数声明function foo(){}
    另一种是通过定义一个变量var foo = function(){}

    function test() {
        foo(); // TypeError "foo is not a function"
        bar(); // "this will run!"
        var foo = function () { // function expression assigned to local variable 'foo'
            alert("this won't run!");
        }
        function bar() { // function declaration, given the name 'bar'
            alert("this will run!");
        }
    }
    test();
    

    var foo首先会上升到函数体顶部,然而此时的fooundefined,所以执行报错。而对于函数bar, 函数本身也是一种变量,所以也存在变量上升的现象,但是它是上升了整个函数,所以bar()才能够顺利执行。

    本文参考自:
    http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html
    https://segmentfault.com/a/1190000003114255
    https://segmentfault.com/a/1190000005794611


    作者博客:pspgbhu

    作者GitHub:https://github.com/pspgbhu

    欢迎转载,但请注明出处,谢谢!

  • 相关阅读:
    【Linux】——sleep无法正常休眠
    【网络——Linux】——IPMI详细介绍【转】
    【Linux】——ctags
    10086 8元套餐
    建置 区域划分
    几何
    孙武
    监察委
    python 内置函数
    Oracle cursor and table
  • 原文地址:https://www.cnblogs.com/pspgbhu/p/5948821.html
Copyright © 2011-2022 走看看