当前位置:首页 > JavaScript

js实现继承原理

2026-03-01 02:51:03JavaScript

JavaScript 继承实现原理

JavaScript 的继承主要通过原型链(Prototype Chain)实现,结合构造函数和原型对象的特性来完成继承关系。以下是几种常见的继承实现方式及其原理。

原型链继承

原型链继承是通过让子类的原型对象指向父类的实例来实现继承。子类实例可以通过原型链访问父类的属性和方法。

function Parent() {
  this.name = 'Parent';
}
Parent.prototype.sayName = function() {
  console.log(this.name);
};

function Child() {}
Child.prototype = new Parent(); // 子类原型指向父类实例

const child = new Child();
child.sayName(); // 输出 'Parent'

缺点:父类的引用类型属性会被所有子类实例共享,修改一个实例的属性会影响其他实例。

构造函数继承

构造函数继承通过在子类构造函数中调用父类构造函数(使用 callapply)实现继承。这种方式可以避免引用类型属性共享的问题。

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']

缺点:父类原型上的方法无法被子类继承。

组合继承

组合继承结合了原型链继承和构造函数继承的优点,既能继承父类的属性,又能继承父类原型上的方法。

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; // 修复构造函数指向

const child = new Child('Child', 10);
child.sayName(); // 输出 'Child'
console.log(child.colors); // ['red', 'blue']

缺点:父类构造函数被调用了两次(Parent.callnew Parent()),效率较低。

原型式继承

原型式继承通过一个临时构造函数实现对象的浅拷贝,类似于 Object.create 的实现方式。

function createObject(obj) {
  function F() {}
  F.prototype = obj;
  return new F();
}

const parent = {
  name: 'Parent',
  colors: ['red', 'blue']
};
const child = createObject(parent);
console.log(child.name); // 'Parent'

缺点:引用类型属性会被所有实例共享。

寄生式继承

寄生式继承在原型式继承的基础上增强对象,添加额外的方法或属性。

function createEnhancedObject(obj) {
  const clone = Object.create(obj);
  clone.sayName = function() {
    console.log(this.name);
  };
  return clone;
}

const parent = { name: 'Parent' };
const child = createEnhancedObject(parent);
child.sayName(); // 输出 'Parent'

缺点:方法无法复用,每个实例都会创建新的方法。

寄生组合式继承

寄生组合式继承是目前最理想的继承方式,通过减少父类构造函数的调用次数来提高效率。

function inheritPrototype(child, parent) {
  const prototype = Object.create(parent.prototype); // 创建父类原型的副本
  prototype.constructor = child; // 修复构造函数指向
  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 child = new Child('Child', 10);
child.sayName(); // 输出 'Child'

优点:只调用一次父类构造函数,避免不必要的属性重复创建,同时保持原型链的完整性。

ES6 的 class 继承

ES6 引入了 classextends 语法,简化了继承的实现,底层仍然是基于原型链的机制。

class Parent {
  constructor(name) {
    this.name = name;
  }
  sayName() {
    console.log(this.name);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 调用父类构造函数
    this.age = age;
  }
}

const child = new Child('Child', 10);
child.sayName(); // 输出 'Child'

特点:语法简洁,易于理解,推荐在支持 ES6 的环境中使用。

js实现继承原理

标签: 原理js
分享给朋友:

相关文章

js实现分页

js实现分页

实现分页的基本思路 分页功能通常需要处理数据分割、页码生成和用户交互。核心逻辑包括计算总页数、根据当前页截取数据、渲染页码按钮等。 前端分页实现(静态数据) 假设已有全部数据,仅需前端分页展示:…

vue的基本实现原理

vue的基本实现原理

Vue 的基本实现原理 Vue.js 的核心实现原理主要围绕响应式系统、虚拟 DOM 和模板编译展开。以下是其关键实现机制的详细说明: 响应式系统 Vue 使用 Object.definePro…

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('image…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点…