# 原型链的问题

原型链虽然很强大,可以用它来实现继承,但是它也存在一些问题。其中,最主要的问题是来自包含引用类型值的原型,它会影响原来的值。

下面我们来看一个实例

# js

下面的代码会说明这个问题

function SuperType() {
    this.colors = ["red","blue","green"];
}
function SubType() {}

//继承来SuperType
SubType.prototype = new SuperType();

var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);  // ["red", "blue", "green", "black"]

var instance2 = new SubType();
console.log(instance2.colors);  // ["red", "blue", "green", "black"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面这个例子我们可以看到当SubType通过原型链继承链SuperType之后,SubType.prototype就变成了SuperType的一个实例,结果SubType的所有实例都会共享这一个colors属性。

借用构造函数,通过apply()和call()方法可以在(将来)新创建的对象上执行构造函数,实现继承且拷贝副本,不影响原有属性。 以下

function SuperType() {
    this.colors = ["red","blue","green"];
}
function SubType() {
    // 继承了SuperType
    SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors)   // ["red", "blue", "green", "black"]
var instance2 = new SubType();
console.log(instance2.colors);  // ["red", "blue", "green"]
1
2
3
4
5
6
7
8
9
10
11
12

以上

参考js高级程序设计第三版6.3——继承

TOC