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; // 修正构造函数指向
})();
相关推荐
shuaijie05182 小时前
强制修改调用接口的api地址。
javascript·vue.js·ecmascript
JerrySir2 小时前
恶意 npm 包只活了 17 分钟:技术面试里,为什么“升级依赖”还不算止血?
javascript·安全
白帽小阳2 小时前
2026前端面试题!(附答案及解析)
javascript·网络·python·安全·web安全·网络安全·护网行动
这是个栗子3 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
Hilaku3 小时前
Vue 和 React 真正的差距,不在语法,而在团队犯错成本
前端·javascript·程序员
研☆香3 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
柯克七七4 小时前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
Null1554 小时前
浏览器唤起桌面端应用(终极篇)
前端·javascript
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十四):后台初始化请求实现
前端·javascript·go
JackieZhengChina4 小时前
零依赖轻量级JS悬浮提示插件title2tip-js的使用教程
开发语言·javascript·ecmascript