js 继承的疑惑

// 1
var Person = function(){
}
Person.level = 1;
Person.prototype.name = "None";
Person.prototype.age = "None";
Person.prototype.arr = new Array(1,2);
var M1 = new Person;
var M2 = new Person;
M1.name = "ZHANG";
M1.arr.push(3);
console.log(M1.arr +"  " +M2.arr);// output : 1,2,3  1,2,3

// 2
function Human(){
    this.arr = new Array(1,2);
}
var p1 = new Human();
var p2 = new Human();
p1.arr.push(3);
console.log(p1.arr +"  " +p2.arr);// output : 1,2,3  1,2

方式1原型继承的arr存储的是数组的引用,导致M1修改后,M2也变了。可是为什么用方式2,改p1.arr却不会影响p2.arr,方式2中存的不是数组的引用吗?
还有看了很多继承的资料,还是不太清楚prototype , __proto__ , constructor之间的关系,大神们能不能帮我理一理他们之间的关系,用实例讲解一下他们之间的继承用法。

阅读 2.5k
3 个回答

在第一个例子中,对M1、M2都是Person的实例,M1、M2的 __proto__是Person.prototype。所以对于M1和M2共享的Person.prototype如果改变了,比如M1.arr.push(3),这两个是会同时变的。但如果写M1.arr = new Array(1,2,3),这个时候是给M1一个新属性arr,不会改变到引用,M2.arr就不会被影响啦。

在第二个例子中,Human是一个构造函数,实例化之后的p1、p2的constructor是Human。通过Human构造方法,p1和p2有各自的arr,所以改变其中一个不会影响到另一个。

参考阅读:
http://zjy.name/archives/javascript-object-oriented-1.html
http://zjy.name/archives/javascript-object-oriented-2.html

构造函数,原型,实例。
通过new构造函数创建实例,实例通过原型链可以访问原型链中的属性。在你上面的第一个例子中,Person是构造函数,Person.prototype是原型,M1M2是实例。

  • 定义在构造函数中的属性是私有属性,通过new创建的实例中的属性是实例本身的属性,它们与其他实例中的属性互不干扰

  • 定义在构造函数原型中的属性是共享属性,通过new创建的实例中的属性不存在于实例中,它们通过原型链找到构造函数原型中的同名属性,它们是共享的。改变一个实例中的属性,另一个实例中的属性也会改变。

建议你对原型(链)有一定的了解后看一下这篇文章:【JavaScript】【对象】更好地理解对象继承

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