一文看懂JavaScript常见继承方式

  • 一、什么是继承
  • 二、继承的实现方式
    • 1、原型式继承
    • 2、构造函数式继承
    • 3、组合式继承
    • 4、Es6继承
    • 5、拷贝式继承
      • ①浅拷贝
      • ②深拷贝

一、什么是继承

官方的定义:

A对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。

二、继承的实现方式

1、原型式继承

原型式继承指的是:将父类的实例作为子类的原型(需要将类的构造器重置)

function Person(name,age){this.name = name;this.age = age;
}
Person.prototype.say=function(){return this.name+','+this.age;
}
var p = new Person("法外狂徒张三",15);function Student(name,age,school){Person.call(this,name,age); //借用构造函数this.school = school;
}
Student.prototype = Object.create(Person.prototype);
//相当于子类的原型等于父类的实例
Student.prototype.constructor= Student;  //改变子类的构造器
Student.prototype.say=function(){//Person.prototype.say.call(this)得到父类的方法return Person.prototype.say.call(this)+","+this.school;
}
var s = new Student("法外狂徒张三","15","清华")
console.log(s.say())

2、构造函数式继承

子类拿不到父类原型上的方法(不需要将类的构造器重置)

构造函数式继承主要是利用了call()和apply()两个方法,想要明白构造函数式继承先得弄明白这两个方法是怎么回事。

apply():调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。

call():调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A,args1,args2);即A对象调用B对象的方法。

/*apply()方法*/
function.apply(thisObj[, argArray])/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

当然,仅仅靠上面的基本解释与代码还是不能理解它们是做什么的。

下面我们看下它们的基本用法。

// 求和
function getSum(num1,num2){return num1+num2;
}
// 求差
function getDiff(num1,num2){return num1-num2;
}// getDiff调用getSum, 特点:里面调用外面
getSum.apply(getDiff,[10,5]);// 15
// getSum调用getDiff
getDiff.apply(getSum,[10,5]);// 5// getDiff调用getSum, 特点:里面调用外面
getSum.call(getDiff,10,5);// 15
// getSum调用getDiff
getDiff.call(getSum,10,5);// 5

由以上的代码我们可以发现,这俩函数的特点都是里面调用外面,真正执行的都是call()或apply()方法的调用者。

弄明白这俩函数的使用方式后我们就可以实现我们需要的构造函数式继承了。

// 父类
function Person(name){this.name = name||'法外狂徒张三';this.sayHello = function(){alert('hello');}
}
Person.prototype.sayGoodbye = function(){alert('goodbye');
}// 子类
// 使用父类的构造函数来增强子类,等于赋值父类的实例属性给子类(不用原型)
function Student(name){// 使用call()方法改变了this指向Person.call(this);this.name = name;
}
let stu = new Student('法外狂徒李四');
stu.name;// '法外狂徒张三'
stu.sayHello();
stu.sayGoodbye();//关于apply方法我们还可以衍生出一些小技巧。
// 利用数学对象的max方法迅速得到数组中的最大数
let arr = [10,2,3,8,17,22,8,21,14];
// 第一个参数null表示不需要改变任何对象的this
console.log(Math.max.apply(null,arr));

3、组合式继承

组合式继承利用的就是原型式继承和构造函数式继承(需要将类的构造器重置)

 // 组合式继承:原型+构造, instanceof,一个实例属于两个类function Person(name,age){this.name = name;this.age = age;}Person.prototype.show = function(){console.log(`我是${this.name},我${this.age}岁了`);}function Student(name,age){Person.call(this,name,age);}Student.prototype = new Person();Student.prototype.constructor = Student;let s1 = new Student('法外狂徒张三',20);console.log(s1);s1.show();

4、Es6继承

class Person {constructor(name,age){this.name = name;this.age = age;}say(){   //Person.prototypereturn this.name+','+this.age;}
}
class Student extends Person {constructor(name,age,school){super(name,age);     //获得父类的属性this.school = school }say(){return super.say()+","+this.school;   //super.say()继父类的方法}
}
var s = new Student("法外狂徒张三",15,"清华");console.log(s.say());

5、拷贝式继承

拷贝式继承也是我们常用的一种手段,但是拷贝也有区分:

浅拷贝:直接赋值拷贝。
深拷贝:将A对象的属性全部复制到B对象上。

①浅拷贝

引用赋值 一改全改

letobj1 = {name:'tom',age:20
};
// 浅拷贝,直接赋值拷贝
let obj2 = obj1;
obj2.height = '180cm';obj1;// {name:'tom',age:20,height:'180cm'}
obj2;// {name:'tom',age:20,height:'180cm'}

②深拷贝

递归赋值

let obj1 = {name:'tom',age:20,hobby:['game','eat']
};
// 定义递归函数
function deepClone(obj){let objClone = Array.isArray(obj)?[]:{};if( obj && typeof obj==='object' ){for( let key in obj ){// 如果是引用数据类型,就使用递归if(obj[key] && typeof obj[key]==='object'){objClone[key] = deepClone(obj[key]);}else{// 如果是基本数据类型就直接复制objClone[key] = obj[key]}}}return objClone;
}
let obj2 = deepClone(obj1);
obj2.hobby.push('haha');
console.log(obj1);
console.log(obj2);

拷贝式继承在之前已详细讲解,因此不在这里赘述,想了解更多的深浅拷贝内容请移步
精致的深浅拷贝

今天博主就总结到这了,有什么想说的是评论区见~

详解JavaScript的五种继承方式相关推荐

  1. 详解二叉树的三种遍历方式(递归、迭代、Morris算法)

    详解二叉树的三种遍历方式(递归.迭代.Morris算法) 最重要的事情写在前面:遍历顺序不一定就是操作顺序!!! 递归解法 首先,一颗二叉树它的递归序列是一定的,导致其前中后序不同的原因只不过是访问节 ...

  2. javascript 的七种继承方式(三)组合继承

    组合继承 前面两篇我们了解到:原型链继承存在着引用类型问题,而借用构造函数又无法实现函数复用和原型方法继承的问题.那么能不能把两者结合一下,取其精华,弃其糟粕?答案是肯定的.那就是接下来我们要介绍的组 ...

  3. linux 网络io命令详解,Linux下五种网络IO模型详解

    本文我们主要来了解一下Unix/Linux下5种网络IO模型:blocking IO, nonblocking IO, IO multiplexing, signal driven IO, async ...

  4. RDMA技术详解——原理和三种实现方式

    RDMA作为一种host-offload, host-bypass技术,使低延迟.高带宽的直接的内存到内存的数据通信成为了可能.目前支持RDMA的网络协议有: 1.InfiniBand(IB): 从一 ...

  5. JavaScript中6种继承方式总结

  6. JavaScript中this的五种绑定方式详解

    1 this的五种绑定方式 1.1 默认绑定 默认绑定是指当函数调用时,没有为其指定对象上下文,此时会将该函数的this绑定到全局对象(window对象).自ES5有了严格模式之后,默认绑定方式又分为 ...

  7. C++的三种继承方式详解

    文章目录 @[toc] C++的三种继承方式详解以及区别 前言 一.public继承 二.protected继承 三.private继承 四.三者区别 五.总结 后话 C++的三种继承方式详解以及区别 ...

  8. Java23种设计模式之单例模式的五种实现方式、反射破解单例模式、不能破解枚举单例模式详解

    源码链接(Gitee码云):https://gitee.com/oldou/javadesignpatterns 这里有我整理好的Java23种设计模式的源码以及博客教程,博客教程中介绍了Java23 ...

  9. es6字符串添加html标签,JavaScript_详解JavaScript ES6中的模板字符串,在 ES6 中引入了一种新的字符 - phpStudy...

    详解JavaScript ES6中的模板字符串 在 ES6 中引入了一种新的字符串字面量 - 模板字符串,除了使用反引号 (`) 表示,它们看上去和普通的字符串没有什么区别.在最简单的情况下,他们就是 ...

  10. JavaScript中的几种继承方式及优缺点,你知道多少呢?

    原文连接:JavaScript中的几种继承方式及优缺点,你知道多少呢? 继承也是前端里面的重要的一个知识点,在实际工作中或者面试中也会经常的遇到,那么通过这篇文章我们详细的了解一下继承的几种方式以及各 ...

最新文章

  1. scrapy安装出错
  2. html css移动form表单位置,表单form的研究
  3. 前端学习(1914)vue之电商管理系统电商系统之创建right分支并把代码推到码云
  4. mysql 二进制 存储格式化_解析MYSQL BINLOG 二进制格式(2)--FORMAT_DESCRIPTION_EVENT
  5. 微信升级最新版本后,可在一对一聊天场景中访问外部链接
  6. QDateTimeEdit使用
  7. 重磅消息,Redis开源作者宣布不再维护Redis项目!
  8. 计算机的使用知识,计算机基础知识计算机的使用方法
  9. 软件测试流程改进的几点看法
  10. 100页ppt讲清楚云原生
  11. Android吉他调音器,吉他调音器:GuitarTuna
  12. 中国农大计算机保研,中国农业大学2021届保研情况
  13. B站CEO陈睿:我们活跃用户仍维持高增长 动能是独特优质内容
  14. 2022-06-清华管理学-清华大学-宁向东
  15. UpdateData用法解释
  16. 刚刚下载的Ubuntu界面过小问题解决方案
  17. linux服务篇-Xinetd服务
  18. java 重写函数_JAVA函数的重载和重写
  19. three.js 07-06 之 Sprite 一幅图片多个精灵
  20. Go:测试库(GoConvey,testify,GoStub,GoMonkey)对比及简介

热门文章

  1. Ubuntu 14.04常用软件的安装
  2. 如何在高通平台新建项目
  3. Openwrt 构建Hello ipk
  4. 浏览器兼容性问题和解决方案
  5. 文献解读|DPP-4i治疗诱导的肠道微生物群的改变可改善葡萄糖稳态
  6. OSX 安装配置Maven
  7. 如何用wps画三线图(最方便最快的方法)
  8. 公司年会要求搞一个抽奖程序,及时安排一波
  9. 基于SSM的ERP管理系统和仓库管理系统
  10. 计算机答辩ppt结论,论文总结与致谢ppt_ppt结束致谢_答辩ppt致谢