导读
1. 构造函数、原型和实例的之间的关系:
每个构造函数都有一个原型对象
prototype
,原型对象包含一个指向构造函数的指针constructor
,而实例都包含一个指向原型对象的内部指针__proto__
。我们可以利用它们的关系,实现原型链继承!
1.1 假设有两个构造函数 Person和Child,它们自身关系如下:

2. 实现原型链继承
function Person(name) {
this.name = name;
this.names = ['大魔王']
}
Person.prototype.say = function() {
console.log('my name is ' + this.name);
}
function Child() {}
const person = new Person('大魔王');
// Child的原型对象被更改为person实例
Child.prototype = person;
Child.prototype.getName = function() {
console.log(this.name);
}
Child.prototype.getNames = function() {
console.log(this.names)
}
var child = new Child();
child.say(); // my name is 大魔王
child.getName(); // 大魔王
2.1 它们新的关系如下:

在上图可以看到,
构造函数Child
的原型对象prototype
被修改为person
实例,
child
实例通过__proto__
指向Child
的原型对象,即person
实例。
console.log(Child.prototype === person) // true
console.log(child.__proto__ === person) // true
3. 原型链继承的缺点
使用原型创建对象会存在多个实例对引用类型的操作
会被篡改的问题,如下:
child.names.push('我不是大魔王');
child.getNames(); // ["大魔王", "我不是大魔王"]
var child2 = new Child();
child2.getNames(); // ["大魔王", "我不是大魔王"]
child
和child2
两个实例的names
属性指向相同,操作其中一个,另一个也会被影响。
3.1 缺点有三 :
- 原型链继承多个实例的引用类型属性指向相同,一个实例修改了原型属性,另一个实例的原型属性也会被修改。
- 不能传递参数。
- 继承单一。
4. tip
有错误请指出,大家互相学习