当前位置:首页 > 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 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClipb…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。 &…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js实现图

js实现图

JavaScript 实现图的常用方法 在 JavaScript 中,图(Graph)可以通过多种方式实现,常见的包括邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix…