一.原型链继承:

原理:将父类的实例作为子类的原型

      function Father(){this.age=10this.phone={first:"华为",second:"小米"}}Father.prototype.getage=function(){return this.age}function Son(name,money){this.name=namethis.money=money}Son.prototype=new Father() //子类型的原型为父类型的一个实例对象Son.prototype.constructor=Son //让子类型的原型的constructor指向子类型Son.prototype.getmoney=function(){return this.money}var son=new Son("小米",1000)//var son2=new Son()console.log(son.age)//10console.log(son.getage())//10console.log(son.name)//小米console.log(son.getmoney())//1000console.log(son instanceof Son)//trueconsole.log(son instanceof Father)//trueson.phone.first="魅族"//更改一个子类的引用属性,其他子类也会受影响console.log(son2.phone.first)//魅族

优点:1.通过子类实例可以直接访问父类原型链上和实例上的成员

2.  相对简单

缺点:1.创建子类实例时,无法向父类构造函数传参

2.父类的所有引用属性会被所有子类共享,更改一个子类的引用属性,其他子类也会受影响

二.构造函数继承:

原理:在子类构造函数中调用父类构造函数,可以在子类构造函数中使用call()apply()方  法改变this指向

      function Father(name,age){this.name=namethis.age={age:age}}Father.prototype.getname=function(){return this.name}function Son(name,age,money){Father.call(this,name,age)//修改Father的thisthis.money=money}Son.prototype.getmoney=function(){return this.money}var son=new Son("小明",12,1000)var son2=new Son("小李",11,999)console.log(son.name)//小明console.log(son.getname())//报错 无法继承父类原型上的属性与方法console.log(son.money)//1000console.log(son.getmoney())//1000console.log(son instanceof Father)//falseconsole.log(son instanceof Son)//trueconsole.log(son.age.age)//12console.log(son2.age.age)//11 父类的引用属性不会被共享

优点:1.可以在子类实例中直接向父类构造函数传参

2.父类的引用属性不会被子类共享

缺点:1.无法继承父类原型上的属性与方法

三.组合继承:

原理:组合上述两种方法就是组合继承。用原型链实现对原型属性和方法的继承,用借用构造函数技术来实现实例属性的继承。

      function Father(name,age){this.name=namethis.age={age:age}}Father.prototype.getname=function(){return  this.name}function Son(name,age,money){Father.call(this,name,age)//能够看到父类型属性this.money=money}Son.prototype=new Father()//能看到父元素方法Son.prototype.constructor=Son//让子类型的原型的constructor指向子类型Son.prototype.getmoney=function(){return this.money}var son=new Son("小明",12,1000)var son2=new Son("小李",18,1999)console.log(son.name)//小明console.log(son.getname())//小明console.log(son.money)//1000console.log(son.getmoney())//1000console.log(son instanceof Father)//trueconsole.log(son instanceof Son)//trueconsole.log(son.age.age)//12console.log(son2.age.age)//18 父类构造函数中的引用属性不会被共享

优点: 1.可以在子类实例中直接向父类构造函数传参
                  2. 通过子类实例可以直接访问父类原型链和实例的成员

3.父类构造函数中的引用属性不会被子类共享

缺点:调用了两次supertype构造函数,一次在赋值Son的原型时,一次在实例化子类时call                                          调用,这次调用会屏蔽原型中的两个同名属性。

四:原型式继承:

原理:利用一个空对象作为中介,将某个对象直接赋值给空对象构造函数的原型。

      function object(obj){function F(){}F.prototype=obj//对传入其中的对象执行了一次浅复制,将构造函数F的原型直接指向传入的对象。return new F()}var person={name:"小李",friends:["小米","小兰"],sayname:function(){console.log(this.name)}}var person1=object(person)person1.name="小王"person1.friends.push("小黑")console.log(person1.friends)//['小米', '小兰', '小黑']person1.sayname()//小王var person2=object(person)person2.name="小鱼"person2.friends.unshift("小葵")console.log(person2.friends)// ['小葵', '小米', '小兰', '小黑']person2.sayname()//小鱼console.log(person.friends)//['小葵', '小米', '小兰', '小黑']

缺点: 1.子类实例不能向父类传参

2.父类的所有引用属性会被所有子类共享

五:寄生式继承

原理: 在原型式继承的基础上,增强对象,返回构造函数

      function object(obj){function F(){}F.prototype=objreturn new F()}function createAnother(obj){var clone=object(obj)clone.getname=function(){    //增强对象console.log(this.name)}return clone}var person={name:"小李",friends:["小米","小兰"],}var person1=createAnother(person)person1.friends.push("小黑")person1.name="小红"console.log(person1.friends)// ['小米', '小兰', '小黑']person1.getname()//小红var person2=createAnother(person)console.log(person2.friends)//['小米', '小兰', '小黑']person2.getname()//小李

缺点: 1.子类实例不能向父类传参

2.父类的所有引用属性会被所有子类共享

(同原型式继承)

六:寄生式组合继承:

原理:结合借用构造函数传递参数和寄生模式实现继承

    function object(obj){function F(){}F.prototype=objreturn new F()}function GetPrototype(Father,Son){var prototype=object(Father.prototype)  // 创建对象,创建父类原型的一个副本prototype.constructor=Son  // 增强对象,弥补因重写原型而失去的默认的constructor 属性Son.prototype=prototype  // 指定对象,将新创建的对象赋值给子类的原型}function Father(name){this.name=namethis.color=["blue","pink","black"]}Father.prototype.getname=function(){return this.name}function Son(name,age){Father.call(this,name)this.age=age}GetPrototype(Father,Son) 这一句,替代了组合继承中的Son.prototype = new Father() Son.prototype.getage=function(){return this.age}var son1=new Son("小米",18)var son2=new Son()son1.color.push("green")console.log(son1.getname())  //小米console.log(son1.name)  //小米console.log(son1.color)  //['blue', 'pink', 'black', 'green']console.log(son2.color)  // ['blue', 'pink', 'black']console.log(son1 instanceof Father)//true

优点:1. 只调用一次父类构造函数

2. 子类可以向父类传参

3. 父类方法可以复用

4. 父类的引用属性不会被共享

                       这是最成熟的方法

七:拷贝继承:

       原理:通过遍历复制前一个对象的属性和方法达到拷贝的效果

    function Father(){this.name="小明",this.phone={first:"小米",second:"华为"}}Father.prototype.getname=function(){return this.name}function Son(name){var father=new Father()for(var i in father){Son.prototype[i]=father[i]}}var son=new Son()var son2=new Son()son.phone.first="小李"console.log(son.name)//小明console.log(son.getname())//小明console.log(son2.phone.first)//小李console.log(son instanceof Father)//false

缺点:1.效率极低,内存占用高(因为要拷贝父类的属性)

2.无法获取父类不可枚举的方法(for in不能访问到的)

3.父类的所有引用属性会被所有子类共享

八:ES6 class继承

      class Father {constructor(name,age){this.name=namethis.age=age}call(){return "打电话"}}//子类继承父类——语法:class 子类 extends 父类class Son extends Father{constructor(name,age,height){//super在子类的构造方法中调用父类的构造方法super(name,age)     //this操作必须放在super后面this.height=height}play(){console.log("玩游戏")}}var son= new Son("小王",16,180)console.log(son.name)//小王console.log(son.call())//打电话console.log(son.height)//180

优点:原理还是参照寄生组合继承,基本原理是一样,语法糖,写起来方便,比较完美

JS继承的几种方式及优缺点相关推荐

  1. js 继承的几种方式

    JS继承的实现方式: 既然要实现继承,那么首先我们得有一个父类,代码如下: function Animal(name) {// 属性this.name = name || '小白';// 实例方法th ...

  2. js对象:实现继承的几种方式及优缺点

    目录 一.原型链继承 二.构造函数继承 三.组合继承(构造函数式继承+原型链继承) 四.拷贝继承(原型式继承) 五.寄生式继承 六.寄生组合式继承 七.使用ES6中class关键字 一.原型链继承 子 ...

  3. 学习js继承的6种方式

    关于原型,原型链,构造函数和实例关系,可以参考上一篇文章 地址:juejin.im/post/5cbfb3- js 实现继承的方式一:原型链继承 function Father(){this.name ...

  4. JS 总结之原型继承的几种方式

    在之前的总结中,我们详细分析了原型<JS 总结之原型>,原型很大作用用于模拟继承,这一次,我们来聊原型继承的几种方式. function Person (age) {this.age = ...

  5. 可以实现继承的几种方式

    继承的几种方式 说起继承,又是一个老生常谈的问题了.今天来讲讲继承的几种方法以及他们的优缺点吧. 源码地址:点击这里 一.原型链继承 原型链继承:通过原型将一个引用类型继承另一个引用类型的属性和方法. ...

  6. 继承有几种方式,分别是什么,想要实现继承可以使用哪些方法

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [继承有几种方式 ...

  7. Django中Model继承的三种方式

    Django中Model继承的三种方式 Django中Model的继承有三种: 1.抽象继承 2.多表继承 3.proxy model(代理model) 1.抽象继承 第一种抽象继承,创建一个通用父类 ...

  8. JavaScript系列-02 HTML嵌入js代码的第二种方式

    javaScript系列 HTML中嵌入js代码的第二种方式 脚本块的方式 文章目录 javaScript系列 前言 一.了解脚本块的方式 1.1运行规则 二.执行原理 1.编写代码 2.效果 总结 ...

  9. spring依赖注入的三种方式以及优缺点

    spring依赖注入的三种方式以及优缺点 一.依赖注入的三种方式 1.通过构造器注入.(spring4.3之后,推荐使用) 2.通过setter注入.(spring4.3之前,推荐使用) 3通过fil ...

  10. 在HTML 中嵌入 JS 代码的三种方式

    一,在HTML中嵌入JS代码的第一种方式:行间事件 行间事件是指将JavaScript函数写到HTML元素中的执行事件. 1.JavaScript 是一种事件驱动型的编程语言,通常都是在发生某个事件的 ...

最新文章

  1. 浏览器--如何让登陆页面的表单不默认显示账号和密码
  2. 招聘|腾讯地图平台部招点云算法工程师
  3. Faster_RCNN 4.训练模型
  4. 第三章、Data语意学
  5. Android自定义XML属性以及遇到的命名空间的问题
  6. C#中深拷贝对象的简单方法
  7. 方法参数是结构体指针,报错信息是空指针怎么办
  8. python 高级面试题_Python高阶面试题
  9. Java 内存模型 JMM 详解
  10. 如何写一个pyton模块
  11. 2017.7.26 奇怪的道路 失败总结
  12. 创业负债累累 | 失败了的我还如何翻盘?是天台见! 我的故事还只是从这件事开始...
  13. python编程入门经典-总算理解python编程入门经典教程
  14. Winfrom窗体无法关闭问题--检查是否存在重写
  15. Codeforces 837D 动态规划
  16. 龙果支付 mysql_龙果开源支付系统搭建与部署
  17. 【笔试题目整理】 网易2018校园招聘数据分析工程师笔试卷
  18. 安卓逆向——AS开发Xposed插件demo案例
  19. PHP 编辑器 kindEditor 上传图片失败 解决方案
  20. 四轮驱动(SSMR)移动机器人手柄控制

热门文章

  1. Chromium OS源码
  2. html yy直播,网页YY直播间进入方法 网页YY迷你版怎么用
  3. 潘多拉网吧防火墙 1.0 双线破解
  4. 最新最全的微信小程序入门学习教程,微信小程序零基础入门到精通
  5. 计算机会考excel操作,信息技术会考EXCEL操作题.doc
  6. mp c2011sp文件服务器,理光Ricoh MP C2011SP驱动
  7. 多点温度检测上位机显示_基于51单片机的多点温度检测系统设计
  8. 自从有了OJ水题嗅探神器,麻麻再也不担心我刷不到题了。。
  9. Android信鸽推送全解
  10. selenium(三)之webDriver与浏览器版本问题