当前位置:首页 > 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']

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

组合继承

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

js实现继承原理

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'

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

寄生式继承

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

js实现继承原理

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实现文件下载

使用 a 标签下载文件 通过动态创建 a 标签并设置 download 属性实现文件下载。适用于已知文件 URL 或 Blob 数据的情况。 function downloadFile(url, f…

vue如何实现原理

vue如何实现原理

Vue 实现原理的核心机制 Vue.js 的核心实现原理基于响应式系统、虚拟 DOM 和组件化设计。以下是关键机制的详细解析: 响应式系统 Vue 通过 Object.defineProperty(…

js实现求导

js实现求导

实现数值求导的方法 在JavaScript中实现求导通常采用数值方法,因为JavaScript不是符号计算语言。以下是常见的数值微分方法: 中心差分法 中心差分法提供较高精度的导数近似:…

js实现授权

js实现授权

授权流程设计 授权流程通常涉及前端与后端的交互,常见方案包括OAuth2.0、JWT等。以JWT为例的典型流程: 用户提交凭证(如用户名密码)到认证服务 服务端验证通过后生成包含用户信息的J…

js实现菜单

js实现菜单

实现基本HTML结构 使用HTML创建菜单的基本框架,通常包含<ul>和<li>元素。示例结构如下: <ul id="menu"> <li><…

js实现轮播代码

js实现轮播代码

基础轮播实现 使用HTML、CSS和JavaScript创建一个简单的轮播效果。HTML部分定义轮播容器和图片元素。 <div class="carousel"> <div c…