js 继承方式有哪几种

1.原型链继承

原理: 通过修改子构造函数的原形对象,使其指向一个父构造函数的实例。这样 子类的实例可以通过原型链访问到父类的属性和方法;

优势:实现简单,代码简洁;

劣势:不能向父类构造函数传递参数 ,且所有子类实例共享父类的引用类型属性,修改其中一个会影响所有实例

实例代码

js 复制代码
function Parent(name){
    this.name = name;
}
Parent.prototype.sayHello = ()=>{
    console.log('hello,'+this.name);
}

function Child(){
    //业务逻辑
    //不能向父类传递参数
}
Child.prototype = New Parent();
var child = New Child();
child.sayHello(); //输出: hello, underiend --因为new Parent()为传参;

2.借用构造函数继承

原理: 在子类构造函数中调用父类构造函数,实现参数传递。

优势: 每个子类实例都有自己独立的属性,不会共享引用类型属性。

劣势: 方法不能复用,每次创建子类实例时都会重新执行父类构造函数。

示例代码:

js 复制代码
function Parent(name){
    this.name = name;
}
Parent.prototype.sayHello = ()=>{
    console.log('hello,'+this.name);
}

function Child(name,grade){
    //call 方法允许你调用一个函数,并且可以指定函数执行时this值;
    Parent.call(this.name) //调用父类构造函数传递参数;
    this.grade = grade;
}
var child = new Child('Alice', 10)
child.sayHello(); //输出: hello, Alice

3.组合继承

即:借用构造函数继承 + 原型链继承

原理:通过借用构造函数继承属性、传递参数,又通过原型链继承父类方法;

优势:结合了原型链继承和方法复用的优点,每个实例有单独的属性(借用构造函数继承优势),方法可以复用;

劣势:父类构造函数会执行2次,效率较低;

示例代码:

js 复制代码
function Parent(name){
    this.name = name;
}
Parent.prototype.sayHello = ()=>{
    console.log('hello,'+this.name);
}

function Child(Name, grade){
    Parent.call(this, name) //借用构造函数继承属性
    this.grade = grade;
}
Child.prototype = Object.create(Parent.prototype); // 原型链继承方法
Child.prototype.constructor = Child; //修正构造函数的指针
var child = new Child('Alice',10)
child.sayHello(); //输出: hello, Alice

4.原型式继承

记住是原型式继承,不是原型链继承,就差一个字

原型式继承(Object.create)

使用Object.create()方法创建一个对象,其原型指向一个已存在的对象。

js 复制代码
const person = {
    name: "John",
    greet: function(){
        console.log(`Hello, my name is ${this.name}`);
    }
}

const john = Object.create(person); //以person为原型创建john对象
john.name = 'jonny'; //修改join的属性,不影响person对象的其他实例或原型链上的属性;
john.greet(); //Hello,my name is jonny;

5.寄生式继承(一种特殊的原型式继承)

创建一个函数,这个函数以某种方式增加对象,然后返回这个对象。通常用于在不改变默认函数的情况下增加。

js 复制代码
function createPerson(original){
    const clone = Object.create(original); //通过原型式继承基本对象的功能
    clone.greet = function(){ //新增方法或属性到克隆对象上
        console.log(`Hello, my name is ${this.name}`);
    }
    return clone; //返回克隆对象,增强了功能版本的对象。
}

6.寄生组合式继承

结合了借用构造函数和原型链继承的优点,通过借用构造函数传递实例属性,通过修改原型链实现方法的共享,同时避免了组合继承中子类构造函数被调用两次的缺点。

js 复制代码
function Parent(name) {
    this.name = name;
}
 
Parent.prototype.sayName = function() {
    console.log(this.name);
};
 
function Child(name, age) {
    Parent.call(this, name); // 借用构造函数继承属性
    this.age = age;
}
 
// 寄生组合式继承的关键部分
(function() {
    // 创建一个没有实例方法的对象或"窃取"函数
    var Super = function() {};
    Super.prototype = Parent.prototype; // 继承Parent的原型方法
    Child.prototype = new Super(); // 实例化Super,并将其赋值给Child的原型
    Child.prototype.constructor = Child; // 修正构造函数指向
})();
相关推荐
杨超凡39 分钟前
豆包收费了?我特么自己用“意念”搓了一个!
javascript
threelab1 小时前
Three.js 咖啡杯烟雾效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
Heo2 小时前
14_React 中的更新队列 updateQueue
前端·javascript·面试
前端 贾公子2 小时前
解决浏览器端 globalThis is not defined 报错
前端·javascript·vue.js
之歆2 小时前
DAY12_CSS3选择器全攻略 + 盒子新特性完全指南(下)
前端·javascript·css3
kyriewen112 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
开发语言·前端·javascript·设计模式·ecmascript
iCxhust3 小时前
在 emu8086 中可以直接编译运行的完整汇编程序,演示数组的定义、遍历、求和、求最大值。
开发语言·前端·javascript·汇编·单片机·嵌入式硬件·算法
JianZhen✓3 小时前
2026前端高频面试题总结(Vue/JS/网络/Webpack/性能优化/手写)
前端·javascript·vue.js
星光开发者4 小时前
基于springboot电动汽车租赁管理系统-计算机毕设 附源码 11217
javascript·spring boot·mysql·django·php·html5·express