Class + extend

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class ColorPoint extends Point {constructor(x, y, color) {super(x, y); // 调用父类的constructor(x, y)this.color = color;}toString() {return this.color + ' ' + super.toString(); // 调用父类的toString()}
}

想了解 Class + extend可以前往ES6——Class 笔记和ES6——Class 的继承 笔记。

原型链

function Parent(){ this.age = 23;
}
Parent.prototype.getAge = function(){ return this.age;
};
function Child(){ this.name = "xd";
} //继承了 Parent
Child.prototype = new Parent();
Child.prototype.getName = function(){ return this.name;
}; var child = new Child();
child.getAge() //23

问题:

  1. 包含引用类型值的原型属性会被所有实例共享。下列代码可以用来说明这个问题:

    function Parent(){ this.friend = ['jh','zh'];
    }
    function Child(){} //继承了 Parent
    Child.prototype = new Parent(); var child1 = new Child();
    child1.friend.push('zf');var child2 = new Child();
    child2.friend   //["jh", "zh", "zf"]
    
  2. 在创建子类型的实例时,不能向超类型的构造函数中传递参数。

借用构造函数

借用构造函数可以解决包含引用类型值的原型属性会被所有实例共享这个问题。

function Parent(){ this.friend = ['jh','zh'];
}
function Child(){//继承了 ParentParent.call(this);
} var child1 = new Child();
child1.friend.push('zf');var child2 = new Child();
child2.friend   //["jh", "zh"]

相对于原型链而言,借用构造函数有一个很大的优势,即可以在子类型构造函数中向超类型构造函数传递参数。

function Parent(age){ this.age = age;
}
function Child(){//继承了 Parent,同时还传递了参数Parent.call(this,23);//实例属性this.name = 'xd';
} var child = new Child();
child.age //23
child.name //'xd'

问题:方法都在构造函数中定义,因此函数复用就无从谈起了。

组合继承(常用)

组合继承的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。

function Parent(age){ this.age = age; this.friend = ['jh','zh'];
}
Parent.prototype.getAge = function(){return this.age;
}
function Child(age, name){//继承了属性Parent.call(this, age);this.name = name;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.getName = function(){return this.name;
}var child1 = new Child(23, 'xd');
child1.friend.push('zf');
child1.age //23
child1.name //'xd'
child1.getName()    //'xd'
child1.getage()    //'23var child2 = new Child(18, 'ah');
child2.friend   //['jh','zh']

原型式继承

原型式继承的思想就是借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

var person1 = { name: "xd", friends: ["jh", "zh"]
}; var person2 = Object.create(person1);
person2.name = "hc";
person2.friends.push("zf"); var person3 = Object.create(person1);
person3.name = "xs";
person3.friends.push("ah"); person1.friends  //["jh", "zh", "zf", "ah"]

在没有必要兴师动众地创建构造函数,而只想让一个对象与另一个对象保持类似的情况下,原型式继承是完全可以胜任的。

问题:包含引用类型值的属性始终都会共享相应的值,就像使用原型模式一样。

寄生式继承

寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象。

var createPerson = function(parent){var child = Object.create(parent);  //通过调用函数创建一个新对象child.sayHi = function(){   //以某种方式来增强这个对象console.log('Hi!');}return child;   //返回这个对象
}var person = {name: 'xd',friend: ['jh', 'zh']
};
var person2 = createPerson(person);
person2.sayHi();    //'Hi!'

问题:使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率;这一点与构造函数模式类似。

寄生组合式继承

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

function inheritPrototype(Child, Parent){ var parent = Object.create(Parent.prototype);    //创建对象parent.constructor = Child;    //增强对象Child.prototype = parent;  //指定对象
}
function Parent(age){this.age = age;this.friend = ['jh','zh'];
}
Parent.prototype.getAge = function(){return this.age;
}
function Child(age, name){Parent.call(this, age);this.name = name;
}
inheritPrototype(Child, Parent);
Child.prototype.getName = function(){return this.name;
}

JS实现继承的七种方法相关推荐

  1. JS遍历对象的七种方法

    我根据阮老师的<ES6标准入门>学习并总结了七种遍历对象的方法,我会将分别介绍这七种方法并进行详细的区分,并将从属性可枚举性问题与遍历方法两个大方面讲述全文,其中可枚举性是掌握遍历对象之前 ...

  2. JS实现继承的几种方法

    父类: // 定义一个动物的类 function Animal (name) {// 属性this.name = name || 'Animal';// 实例方法this.sleep = functi ...

  3. js对象继承的5种方法

    假设现在有a,b两个函数,b函数的实例想要访问a函数的属性和方法(b想要继承a). 1.原型链继承 通过b函数的原型(b.prototype)指向a的实例(new a())来实现,这种继承方法就称为原 ...

  4. js数组去重常见的七种方法

    1.借助ES6提供的Set结构 new Set() 简单好用 强烈推荐 直接给一个新的数组里面,利用es6的延展运算符 var arr = [1,9,8,8,7,2,5,3,3,3,2,3,1,4,5 ...

  5. js中继承的几种用法总结(apply,call,prototype)

    本篇文章主要介绍了js中继承的几种用法总结(apply,call,prototype) 需要的朋友可以过来参考下,希望对大家有所帮助 一,js中对象继承 js中有三种继承方式 1.js原型(proto ...

  6. 前端性能优化的七种方法

    前端性能优化主要有七种方法,包括减少请求数量.减少资源大小.优化网络连接.优化资源加载.减少重绘回流.使用性能更好的API和webpack优化 1.减少请求数量 1.1 图片处理 1.1.1 雪碧图 ...

  7. 创建线程的七种方法 (图解 全网最全最详细)

    本文创建于 2021年5月14日 作者:Xiang 参考文献:创建多线程的四种方法 创建线程的8种方法 创建匿名线程的5种方法 特别鸣谢 文章目录 1.什么是多线程 2.线程状态 3.线程同步方法 4 ...

  8. (转)Shell中获取字符串长度的七种方法

    Shell中获取字符串长度的七种方法 原文:http://blog.csdn.net/jerry_1126/article/details/51835119 求字符串操作在shell脚本中很常用,下面 ...

  9. python 子串是否在字符串中_python七种方法判断字符串是否包含子串

    1. 使用 in 和 not in in 和 not in 在 Python 中是很常用的关键字,我们将它们归类为 成员运算符. 使用这两个成员运算符,可以很让我们很直观清晰的判断一个对象是否在另一个 ...

最新文章

  1. 第十一届山东省大学生程序设计竞赛题解(9 / 13)
  2. 阿里达摩院实习生立功!何恺明Mask R-CNN精度提升,一半输入数据量就行 | CVPR2020...
  3. CentOS 中使用yum时常见的一种提示信息
  4. html div标签的 class属性是干嘛用的?
  5. mysql bandwidth_内存带宽对mysql影响多大
  6. Chapter09-内核模式下的线程同步之事件内核对象
  7. XCTF_Web_新手练习区:backup
  8. javaone_JavaOne 2016后续活动
  9. vue.js框架搭建
  10. linux自动输入sudo密码_用大写字母输入 Linux 命令,实现以 sudo 用户权限运行
  11. 20190826:(leetcode习题)反转链表
  12. 如何让Android手机远离间谍软件?看这里
  13. 什么是UDS诊断协议?
  14. Android原生人脸识别Camera2示例
  15. 永中office属于职称计算机吗,职称计算机考核永中OFFICE辅导之电子表格.doc
  16. 优秀博士生和普通博士生差距能有多大?
  17. ck6.8整合php,CKplayer-超酷网页视频播放器
  18. Digilent Xilinx USB Jtag cable
  19. Golang优秀开源项目汇总(持续更新。。。)
  20. 如何用css写回到顶部,css3 回到顶部书写

热门文章

  1. 你能理解、不能理解和不需要理解的量子计算
  2. KPN iTV的敏捷转型之旅
  3. 搜索关键字高亮显示,就比微信多个多音字搜索
  4. Windows Server 2012配置开机启动项
  5. 谷歌浏览器chrome设置特定网页使用Https(ssl)访问
  6. Web上的支持的图片格式以及它们之间的区别
  7. 出错提示:“Could not flush the DNS Resolver Cache: 执行期间,函数出了问题”的解决方法...
  8. 再谈 document.documentElement 与 document.body 的 scrollWidth、offsetWidth、clientWidth
  9. DBNull与Null的区别
  10. 05 | 服务编排层:Pipeline 如何协调各类 Handler ?