1.基本的原型链继承
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayHello = function() {
console.log(`Hello, I am ${this.name}`);
};
function Child() {
this.childName = 'Child';
}
// 将 Child 的原型对象指向 Parent 的一个实例
Child.prototype = new Parent();
let child = new Child();
child.sayHello();
在这个例子中:
- 首先定义了一个
Parent函数,它有一个name属性和一个sayHello方法。 - 然后定义了一个
Child函数,它有一个childName属性。 - 关键步骤是将
Child的原型对象设置为Parent的一个实例,即Child.prototype = new Parent();。这样Child的实例就可以继承Parent的属性和方法。 - 当创建
Child的实例child并调用sayHello方法时,由于child自身没有sayHello方法,JavaScript 会沿着原型链查找,最终在Parent的原型对象上找到该方法。
2.使用 Object.create 进行更清晰的原型链继承
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayHello = function() {
console.log(`Hello, I am ${this.name}`);
};
function Child() {
this.childName = 'Child';
}
// 使用 Object.create 创建一个新对象,其原型是 Parent 的原型
Child.prototype = Object.create(Parent.prototype);
// 重置 Child 的构造函数,因为它在使用 Object.create 时丢失了
Child.prototype.constructor = Child;
let child = new Child();
child.sayHello();
这里的步骤如下:
- 同样先定义
Parent函数和它的方法。 - 定义
Child函数。 - 使用
Object.create(Parent.prototype)创建一个新对象,这个对象的原型是Parent的原型。这样可以避免调用Parent的构造函数,只继承Parent的原型属性和方法。 - 但是使用
Object.create会导致Child的构造函数丢失,所以需要手动将Child.prototype.constructor设置为Child,以确保child实例的constructor属性指向Child函数。
3.组合继承(借用构造函数和原型链继承)
function Parent(name) {
this.name = name;
} Parent.prototype.sayHello = function() {
console.log(`Hello, I am ${this.name}`);
};
function Child(name, childName) {
// 借用 Parent 的构造函数
Parent.call(this, name);
this.childName = childName;
}
// 继承 Parent 的原型
Child.prototype = new Parent();
Child.prototype.constructor = Child;
let child = new Child('Parent', 'Child');
child.sayHello();
这种方式的特点:
- 定义
Parent函数和它的方法。 - 定义
Child函数,使用Parent.call(this, name);在Child的构造函数中调用Parent的构造函数,将name属性添加到Child的实例中。 - 同时将
Child的原型设置为Parent的实例,继承Parent的原型属性和方法。
4.使用 ES6 的 class 关键字实现继承
class Parent {
constructor(name) { this.name = name;
}
sayHello() {
console.log(`Hello, I am ${this.name}`);
}
}
class Child extends Parent {
constructor(name, childName) {
super(name);
this.childName = childName;
}
}
let child = new Child('Parent', 'Child');
child.sayHello();
这里的步骤如下:
-
使用
class关键字定义Parent类,包含constructor方法和sayHello方法。 -
使用
class Child extends Parent实现继承。 -
在
Child的constructor方法中使用super(name);调用父类的构造函数,并传递name参数。 -
创建
Child的实例并调用sayHello方法。
原型链继承是 JavaScript 中实现对象间继承关系的重要方式,不同的实现方法各有优缺点,在实际开发中可以根据具体情况选择合适的方式。但需要注意的是,在使用原型链继承时,要注意属性和方法的查找顺序,避免意外的结果,例如属性遮蔽等问题。如果要修改父类的原型属性,可能会影响到所有继承该父类的子类。