返回

编程新手必学,javascript的继承方式大解析

前端

JavaScript 继承:理解四种流行方式

在现代应用程序开发中,继承是一项必不可少的技术,它使我们能够创建对象,这些对象可以共享和扩展现有对象的功能。在 JavaScript 中,有多种继承方法可供选择,每种方法都有其独特的优势和适用场景。

原型式继承

原型式继承是 JavaScript 中最简单、最轻量级的继承方法。它通过 Object.create() 方法创建一个新对象,该对象继承了另一个对象的属性和方法。

// Parent 对象
const Parent = {
  name: "Parent",
  age: 42,
  greet() {
    console.log("Hello from Parent!");
  },
};

// 使用原型式继承创建 Child 对象
const Child = Object.create(Parent);

// Child 对象继承了 Parent 的属性和方法
console.log(Child.name); // "Parent"
console.log(Child.age); // 42
Child.greet(); // "Hello from Parent!"

构造函数继承

构造函数继承采用了一种更传统的面向对象编程方法。它创建一个新的构造函数,该构造函数继承了另一个构造函数的属性和方法,使用 super()

// Parent 构造函数
function Parent(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log("Hello from Parent!");
  };
}

// Child 构造函数继承 Parent
function Child(name, age) {
  // 调用 Parent 构造函数来初始化属性
  super(name, age);
}

// Child 对象继承了 Parent 的属性和方法
const child = new Child("John", 30);
console.log(child.name); // "John"
console.log(child.age); // 30
child.greet(); // "Hello from Parent!"

组合式继承

组合式继承结合了原型式继承和构造函数继承的优点。它创建一个新的构造函数,该构造函数使用 super() 继承另一个构造函数,然后将新构造函数的 prototype 对象设置为继承自原型式继承的另一个对象。

// Parent 构造函数
function Parent(name, age) {
  this.name = name;
  this.age = age;
}

// Parent 原型方法
Parent.prototype.greet = function() {
  console.log("Hello from Parent!");
};

// Child 构造函数继承 Parent
function Child(name, age) {
  // 调用 Parent 构造函数来初始化属性
  super(name, age);
}

// Child 原型继承 Parent.prototype
Child.prototype = Object.create(Parent.prototype);
// 重写 Child.prototype.greet 方法
Child.prototype.greet = function() {
  console.log("Hello from Child!");
};

// Child 对象继承了 Parent 的属性和方法
const child = new Child("John", 30);
console.log(child.name); // "John"
console.log(child.age); // 30
child.greet(); // "Hello from Child!"

ES6 Class 继承

ES6 引入了 class 关键字,它提供了一种类似于其他面向对象语言(如 Java 和 C++)的类继承机制。

// Parent 类
class Parent {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  greet() {
    console.log("Hello from Parent!");
  }
}

// Child 类继承 Parent
class Child extends Parent {
  constructor(name, age) {
    // 调用 Parent 构造函数来初始化属性
    super(name, age);
  }
  greet() {
    // 重写 greet 方法
    console.log("Hello from Child!");
  }
}

// Child 对象继承了 Parent 的属性和方法
const child = new Child("John", 30);
console.log(child.name); // "John"
console.log(child.age); // 30
child.greet(); // "Hello from Child!"

常见问题解答

1. 为什么要使用继承?

继承使我们能够重用现有代码,避免重复编写相同的功能,从而创建大型且复杂的应用程序。

2. 哪种继承方式最适合我?

  • 原型式继承:简单、轻量级,适用于单一继承场景。
  • 构造函数继承:传统的面向对象方式,适用于多重继承场景,但相对复杂。
  • 组合式继承:结合了原型式和构造函数继承的优点,避免了它们的缺点,但实现复杂度较高。
  • ES6 Class 继承:类似于其他面向对象语言的类继承,语法简洁,但仅适用于现代浏览器。

3. 继承会影响性能吗?

虽然继承本身不会显著影响性能,但选择合适的继承方式并仔细管理继承层次结构非常重要,以避免性能问题。

4. 如何处理多重继承冲突?

在存在多重继承冲突时,组合式继承和 ES6 Class 继承提供了更灵活的方式来解决冲突。

5. 原型委托和继承有什么区别?

原型委托允许对象将属性和方法委托给另一个对象,而继承创建了新对象,这些新对象共享并扩展了另一个对象的属性和方法。