javascript进修笔记(1)

javascript作用域道理进修

  在每次挪用一个函数的时候,就会进入一个函数内的作用域,当从函数返回
今后,就会返回挪用前的作用域。
  ECMA262关于作用域完成的形貌:

任何实行上下文时候的作用域,都是由作用域链(scope chain)来完成的。
在一个函数被定义的时候,会将它此时的作用域链链接到这个函数对象的[[scope]]属性。
在一个函数被挪用时,会建立一个运动对象,然后关于函数的每个形参,都定名为该运动对象的定名属性,然后将这个运动对象做为此时的作用域链最前端,并将这个函数的[[scope]]属性加入到作用域链中。

用例子申明。来自鸟哥的博客;

function factory() {
     var name = 'Elric';
     var intro = function(){
          alert('I am ' + name);
     }
     return intro;
}

function app(para){
     var name = para;
     var func = factory();
     func();
}

app('eva');

我是这么明白的:
由于

JavaScript中的函数运行在它们被定义的作用域里,而不是它们被实行的作用域里.

所以,intro的作用域链应该是 intro –> factory –> window
当挪用进入到intro时,对name的查找不会进入app的作用域,所以输出的值是Elric

再来一个例子。来自阮一峰先生的微博;

function a(x, y) {
    y = function(){
        x = 2;
    };
    return function() {
        var x = 3;
        y();
        console.log(x);
    }.apply(this, arguments);
}

a();// 3

我是这么明白的:
根据定义来,return的匿名函数的作用域链应该是[[scope]] –> a –>window
所以,在挪用的时候,它最先找到的是本身的x的值,而实行y,修正的是a中的x的值。
如果把代码改成:

function a(x, y) {
    var x = 1;
    y = function() {
        x = 2;
    };
    return function() {
        y();
        console.log(x);
    }.apply(this, arguments);
}

a();// 2

这里输出的原本应该是1,然则!然则实行了y,y把a中的x修正成2.由于y的作用域链是y –>a –>window;

然后,在segmentfault上看到的

function a(x, y) {
    var name = 1;
    y = function() {
        x = 2;
    };
    return function() {
       var name = 3;
        y();
        console.log(this.x);
    }.apply(this, arguments);
}

a();// undefined

我简朴的明白为,这里的this.x相当于window.x。所以是undefined。

总结:

JavaScript中的函数运行在它们被定义的作用域里,而不是它们被实行的作用域里.
从定义出发去剖析函数的作用域,而不是经由过程挪用的递次。

参考资料
1.鸟哥:Javascript作用域道理  
2.明白 JavaScript 作用域和作用域链
3.阮一峰先生微博上的关于js作用域的一道题

    原文作者:Elric_pp
    原文地址: https://segmentfault.com/a/1190000002741505
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞