为什么打印的结果this.a不是10

       function f1() {
            this.a = 1;
            this.b = [1, 2, this.a];
            this.show = function(){
                console.log(this.b)
            }
        }

        function f2() {
            this.a = 2;
        }

        f2.prototype = new f1();

        var a2 = new f2();
        a2.a = 10;
        console.log(a2.show()); //[1,2,1]?
阅读 2.5k
3 个回答

数组存的不是变量

var a = [], b = 1;
a[0] = b;
console.log(a);//[1]
b = 2;
console.log(a); //[1]

function f1() {
  this.a = 1;
  console.log(this);
  this.b = [1, 2, this.a];
  this.show = function() {
    console.log(this);
    console.log(this.b);
  };
}

function f2() {
  this.a = 2;
}

f2.prototype = new f1();
这句话就相当于:

f2.prototype = {
  a: 1,
  b: [1, 2, this.a],
  show: function() {
    console.log(this.b);
  }
};

var a2 = new f2();
再来看这句话相当于:

a2 = {
  a: 2
};

a2.a = 10;
这句话就相当于把上面的a给覆盖了:

a2 = {
  a: 10
};

其中又有这样的关系:
a2.__proto__ == f2.prototype; 这个不需要解释吧,因为a2是f2的实例,教科书就是这么写的

f2.prototype = new f1(); 已知条件

所以我们可以得出:

a2.__proto__ = {
  a: 1,
  b: [1, 2, this.a],
  show: function() {
    console.log(this.b);
  }
};

到这一步已经很清晰明了了, 我们再来看看最关键的一部分

console.log(a2.show());

从上面可以得知的条件:

a2 = {
  a: 10
};

a2.__proto__ = {
  a: 1,
  b: [1, 2, this.a],
  show: function() {
    console.log(this.b);
  }
};

好了,发现 a2 没有 show 属性,那怎么办,沿着原型链也就是 __proto__ 找,最后执行其实就是 a2.__proto__.show(),不信自己去浏览器执行以下,看是不是和 a2.show() 的结果是否一致。

a2.__proto__.show() = function() {
  console.log(this.b);
}

最后就成了这样,接下来我们要研究的就是这个函数执行的 this 是啥,知道this规律应该不难看出来,这里的 this 就是a2.__proto__ ,那么最后就成了 a2.__proto__.b=[1,2,this.a],那么这个 this 指向谁呢?我就不多说了.

其实

a2.__proto__ = {
  a: 1,
  b: [1, 2, this.a],
  show: function() {
    console.log(this.b);
  }
};

还可以这么简化,去掉 this,跟这个是等价的

a2.__proto__ = {
  a: 1,
  b: [1, 2, 1],
  show: function() {
    console.log(this.b);
  }
};

不信把这段代码控制台输入一下,最后运行的结果就是这个,千真万确。

所以最后结果是 [1,2,1]

具体原因如@cc_christian所说。

说句题外话。

a2.a 这个属性是a2的本地属性,你对它的赋值不会去改变a2.__proto__.a的属性。

等于是给a2新增了一个属性。

图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题