当前位置: 首页 > news >正文

说一说js继承的方法和优缺点?

解题思路

得分点

        原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承、ES6 Class

标准回答

        原型链继承:让一个构造函数的原型是另一个类型的实例,那么这个构造函数new出来的实例就具有该实例的属性,原型链继承的。

                优点:写法方便简洁,容易理解。

                缺点:在父类型构造函数中定义的引用类型值的实例属性,会在子类型原型上变成原型属性被所有子类型实例所共享。同时在创建子类型的实例时,不能向超类型的构造函数中传递参数。

        借用构造函数继承:在子类型构造函数的内部调用父类型构造函数;使用 apply() 或 call() 方法将父对象的构造函数绑定在子对象上。

                优点:解决了原型链实现继承的不能传参的问题和父类的原型共享的问题。

                缺点:借用构造函数的缺点是方法都在构造函数中定义,因此无法实现函数复用。在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。

         组合继承:将原型链和借用构造函数的组合到一块。使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性。

                优点:就是解决了原型链继承和借用构造函数继承造成的影响。

                缺点:是无论在什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部

         原型式继承:在一个函数A内部创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。本质上,函数A是对传入的对象执行了一次浅复制。ECMAScript 5通过增加Object.create()方法将原型式继承的概念规范化了。这个方法接收两个参数:作为新对象原型的对象,以及给新对象定义额外属性的对象(第二个可选)。在只有一个参数时,Object.create()与这里的函数A方法效果相同。

                优点是:不需要单独创建构造函数。

                缺点是:属性中包含的引用值始终会在相关对象间共享

        寄生式继承:寄生式继承背后的思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。

                优点:写法简单,不需要单独创建构造函数。

                缺点:通过寄生式继承给对象添加函数会导致函数难以重用。

        寄生组合式继承:通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

                优点是:高效率只调用一次父构造函数,并且因此避免了在子原型上面创建不必要,多余的属性。与此同时,原型链还能保持不变;

                缺点是:代码复杂

加分回答

        ES6 Class实现继承。

                原理:原理ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。 ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。需要注意的是,class关键字只是原型的语法糖,JavaScript继承仍然是基于原型实现的。

                优点:语法简单易懂,操作更方便。

                缺点:并不是所有的浏览器都支持class关键字 lass Person { //调用类的构造方法 constructor(name, age) { this.name = name this.age = age } //定义一般的方法 showName() { console.log("调用父类的方法") console.log(this.name, this.age); } } let p1 = new Person('kobe', 39) console.log(p1) //定义一个子类 class Student extends Person { constructor(name, age, salary) { super(name, age)//通过super调用父类的构造方法 this.salary = salary } showName() {//在子类自身定义方法 console.log("调用子类的方法") console.log(this.name, this.age, this.salary); } } let s1 = new Student('wade', 38, 1000000000) console.log(s1) s1.showName()

相关文章:

  • ARMv8/ARMv9的Exclusive机制深度解读
  • 机器学习——梯度下降算法
  • 64.【网络编程】
  • Python爬虫-网页认识
  • 面试官:深度不够,建议回去深挖
  • [ vulhub漏洞复现篇 ] Apache APISIX 默认密钥漏洞 CVE-2020-13945
  • 接口测试用例生成工具介绍及应用
  • C#接入 NPOI
  • 面试百问:项目上线后才发现bug怎么办?
  • SpringBoot+Vue实现前后端分离网上药店平台
  • Simulink 自动代码生成电机控制:基于Keil软件集成
  • LQ0103 子串分值【字符串】
  • 数据库实战经验分享(全量表,增量表,拉链表,流水表,快照表)
  • 【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
  • [附源码]Java计算机毕业设计SSM电力公司员工安全培训系统
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • Docker: 容器互访的三种方式
  • leetcode46 Permutation 排列组合
  • Python十分钟制作属于你自己的个性logo
  • Python语法速览与机器学习开发环境搭建
  • QQ浏览器x5内核的兼容性问题
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • underscore源码剖析之整体架构
  • Vue--数据传输
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 开发基于以太坊智能合约的DApp
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 责任链模式的两种实现
  • 最简单的无缝轮播
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​linux启动进程的方式
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​用户画像从0到100的构建思路
  • # 透过事物看本质的能力怎么培养?
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (02)vite环境变量配置
  • (06)Hive——正则表达式
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (三)elasticsearch 源码之启动流程分析
  • (十六)Flask之蓝图
  • (一)80c52学习之旅-起始篇
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .Net的C#语言取月份数值对应的MonthName值
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术