猿问

作用域的问题

console.log(a);


function test() {

   a = 1;

}

test(); // 报错 

第一个问题: 

js是词法作用域不是动态作用域,也就是在代码写完时作用域就已经形成了,那么上面的那段代码在函数没有执行的时候在变量a没有声明的时候不是应该给window添加对应的这个属性名吗?这样无论函数是否一样会打印undefined的啊?


还有函数执行与否会影响打印结果,不就是变成动态作用域了吗?


同样还是第一个问题的引申,当函数内部的变量没有定义时,该变量是作为全局变量的,结合上面的案例我就更难理解了


function getProduct(num1, num2) {

    product = num1 * num2;

    return product;

}

var product = 10;

var number = getProduct(20, 20);

alert(product);//得到的弹出框是400

下面是第二个问题


    var num = 10;

    function test(){

      console.log(num);

    }

    

    function test1(){

      var num = 100;

      test();

    }

    

    test1(); // 10

第二个问题: test函数的执行环境是test1作用域,所以会优先找test1中的变量num,为什么会是window中的变量?


一只甜甜圈
浏览 308回答 1
1回答

莫回无

很感激这么多朋友的回答,给我提供很多帮助,本人比较愚钝,还是不大明白所以又翻了一遍《javascript高级程序设计》这本书,感觉清晰了很多,所以我觉得我的回答还是比较中肯的,所以自问自答了,如果有不妥的地方欢迎指出(根据javascript高级程序设计第四章)解析上面的代码js中存在全局执行环境和由函数形成的局部执行环境这两种,统称为执行环境(这里可以理解成作用域);执行环境都会对应一个变量对象,包含当前环境的变量和函数(函数中的参数也作为函数执行环境的变量,即函数所在作用域的局部变量);只有当函数执行时会形成作用域链,作用域链的前端始终是当前执行代码所在的执行环境对应的变量对象,往后是下一个(外部)变量对象,直到最外边的全局执行环境的变量对象(所谓的作用域链就是变量对象组成的一条线);变量对象中变量的解析查找就是沿着作用域链一级一级查找;如果执行环境中的变量没有用var声明,那么在函数执行时(这样才会形成作用域链)会沿着作用域链一级一级查找变量对象,如果没有找到则会在全局变量对象中声明该变量。综上,上面的代码可以改写成下面这样function test() {   a = 1;}test();console.log(a); // 只能放在函数执行后面才会打印出undefined同样第二个问题,首先要明白一点,只有在函数内部定义的函数,其在执行时作用域链才会包括外部函数的活动对象,下面该问题中test函数不是在函数test1中定义的,所以当test执行时,作用域链只有当前活动对象和全局变量对象。var num = 10;function test(){  console.log(num);}function test1(){  var num = 100;  test();}test1(); // 10
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答