变量的作用域和变量提升

来源:互联网 发布:淘宝卖家快点到货款 编辑:程序博客网 时间:2024/04/27 19:18

京东面试题,面试官小姐姐给出了一道题:

var a = 100;function test(){    console.log(a);    a = 10;    console.log(a);    console.log(this.a);    var a;}test();

问我这三个会打印出来的值是什么?

好吧我这个还以为是要考我闭包的问题,后来一想是个变量提升的问题(好吧好吧,是小姐姐看我太尴尬了,就给我讲了一下)

回来研究一下这个变量的作用域和变量提升:

一、作用域:

一个变量的作用域(scope)是程序源代码中定义这个变量的区域。
全局变量拥有全局作用域,在javaScript代码中任何地方都有定义的。
然而在函数内声明的变量只是在函数内部有定义,他们是局部变量,作用域也只是在局部。

在函数体内,局部变量的优先级要高于全局变量。如果在函数体内重新声明一个与局部变量重名的变量,局部变量就会覆盖全局变量的值。
来看个例子:

var num="100";function scope(){    var num="10";    function innerScope(){        var num = "1";        console.log(scope);//输出:1    }    innerScope();    console.log(num);//输出:10}scope();console.log(num);//输出:100

这个例子会打印三个数,分别是1,10,100;
局部变量的作用域仅仅在函数内部,出了函数体之后,局部变量就会被销毁。
在innerScope()函数中,虽然又声明了一个num,但是innerScope()中的num是局部变量,只是与全局变量的名字相同,并不是全局变量,所以,虽然在该函数中把num赋值为1,但这仅仅是一个与全局变量名称相同的一个变量而已,并没有改变全局变量的值。

再来看一个例子:

var num="100";function scope(){    var num="10";    function innerScope(){        num = "1";        console.log(scope);//输出:1    }    innerScope();    console.log(num);//输出:1}scope();console.log(num);//输出:100

上面这部分代码中,在innerScope()函数中,我们并没有用var来声明num,所以,在这里的num的作用域就被提升了,即我们将scope中的num的值重置了,所以在输出的时候输出的结果为嵌套作用域内的局部变量。

二、变量提升

在Javascript中,函数及变量的声明都将被提升到函数的最顶部。
在js中,变量的声明会被解析器悄悄的提升到方法体的最顶部,但是需要注意的是,提升的仅仅是变量的声明,变量的赋值并不会被提升,我们需要注意的是,函数的声明与变量的声明是不一样的。函数的函数体也会被一起提升。
函数表达式和变量表达式只是其声明被提升,函数声明是函数的声明和实现都被提升。

所以上面那个题就很好理解了。
我们再来看一下这个题:

var num="100";function scope(){    var num="10";    function innerScope(){        var num = "1";        console.log(scope);//输出:1    }    innerScope();    console.log(num);//输出:10}scope();console.log(num);//输出:100
  1. 因为变量提升,a提升到最前面,声明未赋值,所以第一个就会打印undefined;
  2. 第二个在a声明之后,而且a赋值为10,所以第二个打印出来10;
  3. 第三个,因为test()是在window下调用的;this指的是test()调用的作用域,所以第三个打印100;

看一个函数提升的例子:

<script language="javascript" type="text/javascript">        //在全局对象中声明两个全局函数,反模式      function foo()      {          alert("global foo");      }      function bar()      {          alert("global bar");      }      //定义全局变量      var v = "global var";      function hoistMe()      {          alert(typeof foo); //function          alert(typeof bar); //undefined          alert(v); //undefined          //为什么bar函数和变量v是未定义而不是全局变量中定义的相应的函数变量呢?           //因为函数里面定义了同名的函数和变量,无论在函数的任何位置定义这些函数和           //和变量,它们都将被提升到函数的最顶部。          foo(); //local foo          bar(); //报错,TypeError "bar is not a function"        //函数声明,变量foo以及其实现被提升到hoistMe函数顶部          function foo()          {              alert("local foo");          }          //函数表达式,仅变量bar被提升到函数顶部,实现没有被提升          var bar = function()          {              alert("local bar");          };          //定义局部变量           var v = "local";      }      (function()      {          hoistMe();      })();     //函数表达式和变量表达式只是其声明被提升,函数声明是函数的声明和实现都被提升。      /**由于函数提升的效果,hoistMe方法相当于     function hoistMe()     {         //函数声明,变量foo以及其实现被提升到hoistMe函数顶部         function foo()         {             alert("local foo");         }          //函数表达式,仅变量bar被提升到函数顶部,实现没有被提升(同变量提升)         var bar = undefined;         //变量声明被提升          var v = undefined;         alert(typeof foo); //function         alert(typeof bar); //undefined         alert(v); //undefined         foo(); //local foo         bar(); //报错,缺少对象         bar = function()         {             alert("local bar");         };        v = "local";     }     */  </script>  
原创粉丝点击