位置: 文档库 > JavaScript > 文档下载预览

《JS的继承方法总结(附案例).doc》

1. 下载的文档为doc格式,下载后可用word或者wps进行编辑;

2. 将本文以doc文档格式下载到电脑,方便收藏和打印;

3. 下载后的文档,内容与下面显示的完全一致,下载之前请确认下面内容是否您想要的,是否完整.

点击下载文档

JS的继承方法总结(附案例).doc

《JS的继承方法总结(附案例)》

JavaScript作为一门基于原型的动态语言,其继承机制与传统的类式继承存在本质差异。理解JS的继承方式不仅能帮助开发者写出更高效的代码,还能在解决复杂业务场景时提供灵活的解决方案。本文将系统梳理JS中常见的继承方法,结合实际案例分析其适用场景,并对比不同方法的优缺点。

一、原型链继承

原型链继承是JS中最基础的继承方式,通过将子类的原型指向父类的实例实现继承。其核心原理是利用原型对象的__proto__属性形成链式关系。

function Parent() {
  this.name = 'Parent';
  this.colors = ['red', 'blue'];
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child() {
  this.name = 'Child';
}
Child.prototype = new Parent(); // 关键步骤

const child1 = new Child();
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = new Child();
console.log(child2.colors); // ['red', 'blue', 'green'](共享引用问题)

原型链继承存在两个主要问题:1)所有子类实例共享父类构造函数的引用属性;2)创建子类实例时无法向父类构造函数传参。这种继承方式适合需要简单原型扩展的场景,但不适用于需要独立属性的对象。

二、借用构造函数继承

借用构造函数继承(又称经典继承)通过call/apply方法在子类构造函数中调用父类构造函数,实现每个实例拥有独立属性副本的效果。

function Parent(name) {
  this.name = name;
  this.colors = ['red', 'blue'];
}

function Child(name) {
  Parent.call(this, name); // 关键步骤
}

const child1 = new Child('Child1');
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = new Child('Child2');
console.log(child2.colors); // ['red', 'blue'](独立副本)

该方法解决了引用属性共享的问题,且支持传参,但存在缺陷:1)无法复用父类原型上的方法;2)每个子类实例都要复制父类构造函数的所有属性和方法,造成内存浪费。适用于需要完全隔离属性的简单场景。

三、组合继承(原型链+借用构造函数)

组合继承结合了前两种方法的优点,通过原型链继承父类原型方法,通过借用构造函数继承父类实例属性。

function Parent(name) {
  this.name = name;
  this.colors = ['red', 'blue'];
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child(name, age) {
  Parent.call(this, name); // 继承属性
  this.age = age;
}
Child.prototype = new Parent(); // 继承方法
Child.prototype.constructor = Child; // 修复constructor指向

const child1 = new Child('Child1', 10);
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = new Child('Child2', 12);
console.log(child2.colors); // ['red', 'blue']
child1.sayName(); // 'Child1'

组合继承是JS中最常用的继承模式,解决了原型链和借用构造函数各自的问题。但存在父类构造函数被调用两次的问题(一次在子类原型,一次在子类构造函数),虽然不影响功能但存在性能浪费。

四、原型式继承

原型式继承基于已有对象创建新对象,本质是对原型链继承的简化实现,适用于不需要复杂构造函数的情况。

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

const parent = {
  name: 'Parent',
  colors: ['red', 'blue'],
  sayName: function() {
    console.log(this.name);
  }
};

const child1 = object(parent);
child1.name = 'Child1';
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = object(parent);
console.log(child2.colors); // ['red', 'blue', 'green'](共享引用)

ES5新增的Object.create()方法实现了相同功能:

const child = Object.create(parent, {
  name: { value: 'Child' }
});

该方法适合快速创建基于现有对象的子对象,但同样存在引用属性共享的问题,且无法实现构造函数参数传递。

五、寄生式继承

寄生式继承在原型式继承基础上,通过增强对象来添加额外功能,类似于工厂模式。

function createChild(original) {
  const clone = Object.create(original);
  clone.sayAge = function() {
    console.log(this.age);
  };
  return clone;
}

const parent = {
  name: 'Parent',
  age: 40
};

const child = createChild(parent);
child.sayAge(); // 40

这种方法适合需要为对象添加特定方法的场景,但每次创建对象都要执行一次增强操作,无法复用方法,且同样存在引用属性问题。

六、寄生组合式继承(最优方案)

寄生组合式继承是当前JS中最理想的继承方式,通过借用构造函数继承属性,通过寄生方式继承原型方法,避免了组合继承中父类构造函数被调用两次的问题。

function inheritPrototype(child, parent) {
  const prototype = Object.create(parent.prototype); // 创建父类原型副本
  prototype.constructor = child; // 修复constructor
  child.prototype = prototype; // 赋值给子类原型
}

function Parent(name) {
  this.name = name;
  this.colors = ['red', 'blue'];
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child(name, age) {
  Parent.call(this, name); // 继承属性
  this.age = age;
}
inheritPrototype(Child, Parent); // 继承方法

const child1 = new Child('Child1', 10);
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = new Child('Child2', 12);
console.log(child2.colors); // ['red', 'blue']

该方法只调用一次父类构造函数,避免了不必要的属性复制,同时保持了原型链的完整性,是ES5环境下最完善的继承方案。

七、ES6 Class继承

ES6引入的class语法提供了更接近传统面向对象语言的继承方式,底层仍基于原型链实现。

class Parent {
  constructor(name) {
    this.name = name;
    this.colors = ['red', 'blue'];
  }
  sayName() {
    console.log(this.name);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 必须调用super
    this.age = age;
  }
  sayAge() {
    console.log(this.age);
  }
}

const child1 = new Child('Child1', 10);
child1.colors.push('green');
console.log(child1.colors); // ['red', 'blue', 'green']

const child2 = new Child('Child2', 12);
console.log(child2.colors); // ['red', 'blue']

ES6的class继承具有以下特点:1)语法更简洁;2)强制要求调用super();3)原型关系自动处理;4)支持静态方法继承。虽然本质仍是原型继承,但提供了更清晰的语法结构,是现代JS开发的首选方案。

八、继承方法对比

方法 优点 缺点 适用场景
原型链继承 简单直接 共享引用属性、无法传参 简单原型扩展
借用构造函数 独立属性、支持传参 无法复用方法、内存浪费 需要完全隔离的场景
组合继承 功能完善 调用两次父类构造 通用继承需求
原型式继承 快速创建对象 共享引用属性 基于现有对象的扩展
寄生式继承 灵活增强 无法复用方法 需要特定方法的场景
寄生组合式 最优方案 实现稍复杂 ES5环境下的最佳实践
ES6 Class 语法清晰 需要ES6+环境 现代JS开发

九、实际应用案例

以电商平台的商品分类系统为例,展示不同继承方式的实际应用:

// 基础商品类
class Product {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
  getInfo() {
    return `ID: ${this.id}, Name: ${this.name}`;
  }
}

// 电子类商品(ES6继承)
class Electronics extends Product {
  constructor(id, name, warranty) {
    super(id, name);
    this.warranty = warranty;
  }
  getWarranty() {
    return `${this.name}的保修期为${this.warranty}个月`;
  }
}

// 服装类商品(寄生组合式继承)
function Clothing(id, name, size) {
  Product.call(this, id, name);
  this.size = size;
}
inheritPrototype(Clothing, Product);
Clothing.prototype.getSize = function() {
  return `${this.name}的尺码为${this.size}`;
};

// 创建实例
const phone = new Electronics('P001', '智能手机', 24);
const shirt = new Clothing('C001', 'T恤', 'XL');

console.log(phone.getInfo()); // ID: P001, Name: 智能手机
console.log(phone.getWarranty()); // 智能手机的保修期为24个月
console.log(shirt.getInfo()); // ID: C001, Name: T恤
console.log(shirt.getSize()); // T恤的尺码为XL

关键词:JavaScript继承、原型链继承、借用构造函数、组合继承、原型式继承、寄生式继承、寄生组合式继承、ES6 Class继承、对象创建模式、面向对象编程

简介:本文系统总结了JavaScript中八种主流继承方法,包括原型链继承、借用构造函数继承、组合继承等传统方案,以及ES6 Class继承等现代实现。通过代码案例详细分析了每种方法的实现原理、优缺点和适用场景,帮助开发者根据实际需求选择最合适的继承方案,提升代码质量和开发效率。

《JS的继承方法总结(附案例).doc》
将本文以doc文档格式下载到电脑,方便收藏和打印
推荐度:
点击下载文档