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; // 修正构造函数指向
})();
相关推荐
yuezhilangniao3 小时前
AI智能体全栈开发工程化规范 备忘 ~ fastAPI+Next.js
javascript·人工智能·fastapi
铅笔侠_小龙虾5 小时前
Flutter Demo
开发语言·javascript·flutter
2501_944525545 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
wangdaoyin20105 小时前
若依vue2前后端分离集成flowable
开发语言·前端·javascript
天天进步20155 小时前
AI Agent 与流式处理:Motia 在生成式 AI 时代的后端范式
javascript
心柠5 小时前
vue3相关知识总结
前端·javascript·vue.js
常年游走在bug的边缘7 小时前
掌握JavaScript作用域:从函数作用域到块级作用域的演进与实践
开发语言·前端·javascript
极致♀雨7 小时前
vue2+elementUI table表格勾选行冻结/置顶
前端·javascript·vue.js·elementui
林shir7 小时前
3-15-前端Web实战(Vue工程化+ElementPlus)
前端·javascript·vue.js
换日线°8 小时前
前端炫酷展开效果
前端·javascript·vue