搜尋

首頁  >  問答  >  主體

javascript - 一个没有理解面试题

 var tt = 'aa';   

 function test(){

       alert(tt);
       var tt = 'dd';
       alert(tt);    

       }   

  test();

为什么第一个弹出undifine呢?

又:

 var tt = 'aa';

 function test(){


  alert(tt);

  //var tt = 'dd';
  //alert(tt);

        }

   test();

弹出aa?

求各位大神解答下

PHP中文网PHP中文网2895 天前680

全部回覆(19)我來回復

  • 迷茫

    迷茫2017-04-10 15:22:37

    这题总结下来就2点知识:
    1. 声明提升
    2. 作用域链

    先说后者,js在访问一个变量时会优先在该作用域(访问时的那个作用域)内寻找是否声明过该变量,如果该变量已经存在,则直接使用它的值,否则它会寻找该作用域的‘父作用域/上级作用域’,以此类推,直到找到全局作用域为止。

    关于声明提升是指:js在解析的时候总是会将var, function这类关键词的声明语句提升至该作用域的最顶部(注意:这里只会提升声明部分)。

    于是你那段代码等价于下面

    javascriptvar tt = 'aa';   
    
    function test(){
        var tt; //这个tt未被赋值,按js的‘规矩’,它的值是`undefined`
        alert(tt);
        tt = 'dd';
        alert(tt);    
    }   
    
    test();
    

    所以执行的时候返回的是 undefineddd.


    广告
    更多精彩内容你或许不知道的javascript,css细节

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-10 15:22:37

    这样是全局的:

    javascriptvar tt = 'aa';
    function test() {
        alert(tt);
    }
    test();
    

    这是你的例子:

    javascriptvar tt = 'aa';
    function test() {
        alert(tt);
        var tt = 'dd';
        alert(tt);
    }
    test();
    

    在函数内部使用var声明变量,是局部的。优先级高于函数外部的全局变量。
    这个说明js解释器的解析顺序,尽管你的alert(tt)var tt = 'dd'前面,但是它还是认为你是在内部定义了一个局部变量。

    javascriptfunction test() {
        var tt;
        alert(tt);
        tt = 'dd';
        alert(tt);
    }
    

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-10 15:22:37

    这个是 js 的作用域和提升的问题,参考这篇文章 http://dyy.im/4406.html

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-10 15:22:37

    这是JS的解释机制,第一个会理解成:
    function test(){
    var tt;
    alert(tt);
    tt = 'dd';
    alert(tt);
    }

    这个时候函数内作用域的 tt 优先于外面的 tt

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:22:37

    函数内的变量也会有类似函数声明提升的效果,test内的相当于
    function test(){
    var tt; //先定义,但未赋值。这里把全局(或者父函数)的tt给覆盖了
    alert(tt);
    tt = 'dd'; //这里才给tt赋值。
    alert(tt);
    }

    回覆
    0
  • 黄舟

    黄舟2017-04-10 15:22:37

    我来将整个执行过程给你捋一捋哈

    0.明白一个机制: 开始执行Js文件时,它会先扫描下整个js文件再去执行代码,会创建全局对象,搜索函数外面的 “var” 声明语句(此时并未赋值,为undefined),
    在这面试题中,在全局对象中创建 tt 属性,tt = undefined,创建全局的执行环境,作用域链只有一个对象:全局对象
    1.代码执行过程: var tt = 'aa';变量名解析开始,在全局对象属性中查找tt属性,把"aa"赋给tt。
    跳过函数声明
    test();遇到test()函数调用:创建调用对象
    搜索函数中的var声明语句和参数,在调用对象中创建tt的属性,tt=undefined (这里很重要,tt现在是undefined)
    创建函数执行环境,作用域链:调用对象>全局对象
    回到函数,依次执行代码:
    alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为undefined,执行弹出undefined,(这就是为什么了)
    var tt="dd",查询tt,变量名解析,先搜索调用对象,找到tt属性,tt="dd"
    alert(tt),查询tt,变量名解析,先搜索调用对象,找到tt属性,其值为"dd",执行弹出dd

    这个问题涉及到函数的执行环境和作用域链,建议你去了解下哦。第二个函数你应该懂了不用解释了吧。

    求采纳啊

    回覆
    0
  • 黄舟

    黄舟2017-04-10 15:22:37

    详解见javascript变量声明提升(hoisting) - SegmentFault

    回覆
    0
  • 阿神

    阿神2017-04-10 15:22:37

    知道代码是分两个阶段执行就行了
    解析和进入上下文[变量 函数等声明]阶段
    第二个阶段是代码执行

    回覆
    0
  • 高洛峰

    高洛峰2017-04-10 15:22:37

    js的作用域不是块作用域而是函数作用域
    这个是js变量的声明提前

    回覆
    0
  • 黄舟

    黄舟2017-04-10 15:22:37

    主要考点就是变量申明提前 到作用域内的顶部

    回覆
    0
  • 取消回覆