JavaScript中的原型继承实现

67 阅读1分钟

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();

在这个例子中:

  1. 首先定义了一个 Parent 函数,它有一个 name 属性和一个 sayHello 方法。
  2. 然后定义了一个 Child 函数,它有一个 childName 属性。
  3. 关键步骤是将 Child 的原型对象设置为 Parent 的一个实例,即 Child.prototype = new Parent(); 。这样 Child 的实例就可以继承 Parent 的属性和方法。
  4. 当创建 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();

这里的步骤如下:

  1. 同样先定义 Parent 函数和它的方法。
  2. 定义 Child 函数。
  3. 使用 Object.create(Parent.prototype) 创建一个新对象,这个对象的原型是 Parent 的原型。这样可以避免调用 Parent 的构造函数,只继承 Parent 的原型属性和方法。
  4. 但是使用 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();

这种方式的特点:

  1. 定义 Parent 函数和它的方法。
  2. 定义 Child 函数,使用 Parent.call(this, name); 在 Child 的构造函数中调用 Parent 的构造函数,将 name 属性添加到 Child 的实例中。
  3. 同时将 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();

这里的步骤如下:

  1. 使用 class 关键字定义 Parent 类,包含 constructor 方法和 sayHello 方法。

  2. 使用 class Child extends Parent 实现继承。

  3. 在 Child 的 constructor 方法中使用 super(name); 调用父类的构造函数,并传递 name 参数。

  4. 创建 Child 的实例并调用 sayHello 方法。

原型链继承是 JavaScript 中实现对象间继承关系的重要方式,不同的实现方法各有优缺点,在实际开发中可以根据具体情况选择合适的方式。但需要注意的是,在使用原型链继承时,要注意属性和方法的查找顺序,避免意外的结果,例如属性遮蔽等问题。如果要修改父类的原型属性,可能会影响到所有继承该父类的子类。