阮一峰先生微博上的关于js作用域的一道题

在阮一峰先生的微博上看到如许一道题

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

a();

问:输出是多少?为何?

我想到了答案,而且考证准确,小高兴,在这里写下解题思绪:

  • 这道题的疑惑许多
  • return实在没用,代码能够变成
javascriptfunction a(x, y) {
    y = function(){
        x = 2;
    };
    (function() {
        var x = 3;
        y();
        console.log(x);
    }).apply(this, arguments);
}

a();
  • 实行a();实际上是实行
javascriptfunction() {
    var x = 3;
    y();
    console.log(x);
}apply(this, arguments);

个中:1. this是跟作用域(浏览器环境下是window,node环境下是global),由于是在跟作用域下实行的a();。 2. arguments是空,由于a();没有参数。

  • y();没用。由于y定由于函数起首定义了var x = 3;,所以console.log(x)就是3。由于作用域优先级是从内向外由高到低的,所以在这里var x = 3;的优先级是最高的,y();中不论定义的什么,都不会影响到x。所以之前剖析了那么多,实在都没用啊!做题时读代码,递次要从内部到外部(仅限于做题)~

问题:这道题假如将输出改成console.log(this.x),答案会是什么? 我认为是2,但是效果确切undefined,这是为何呢? 现在我还没搞邃晓,求解。

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

a();

补充

我弄邃晓了上面的问题,重点在于:1. 函数y的作用域,2. 函数a中定义的变量

之前我说y();没用,为何没用?是由于函数y是定义在函数a下的,所以y的作用域链是如许的:

window

a

y

由于函数a是如许定义的:function a(x, y),所以函数a定义了变量x,所以y中的x = 2;赋值给了函数ax参数。并没有赋值给window作用域下的xconsole.log(this.x);this指的是window,所以输出为undefined。

假如将函数a的参数去掉,问题变成:

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

a();

如许函数a中就没有x这个变量了,所以函数y中的x = 2;就会赋值给跟作用域下的x,所以console.log(this.x);的输出就会变成2

再将问题改一下,假如将函数y()定义在return 的匿名函数内里,问题变成:

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

a();

console.log(x)会输出什么? 答案是2,由于此时y的作用域链是如许的:

window

a

匿名函数

y

由于匿名函数中定义了var x = 3;,所以函数y中的x = 2;就会修正匿名函数中的x的值,所以console.log(x)输出变成了3,

弄邃晓这道题的每一处细节,对明白javascript言语的作用域很有协助。虽然这道题对编程自身没有什么意义。

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