原型式继承

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

function create(o){    function F(){}  F.prototype = o;   return new F();
}

在 create() 函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。

ECMAScript 5通过新增 Object.create() 方法规范化了原型式继承。这个方法接收两个参数:一个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。在传入一个参数的情况下, Object.create() 与 create() 方法的原理相同。

let person = {  name: 'Nicholas', friends: ['Shelby', 'Court', 'Van']
};
let anotherPerson = Object.create(person);
anotherPerson.name = 'Greg';
anotherPerson.friends.push('Rob');
let yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = 'Linda';
yetAnotherPerson.friends.push('Barbie');
alert(person.friends); // 'Shelby,Court,Van,Rob,Barbie'

Object.create() 方法的第二个参数与 Object.defineProperties() 方法的第二个参数格式相同:每个属性都是通过自己的描述符定义的。以这种方式指定的任何属性都会覆盖原型对象上的同名属性。

let person = {    name: 'Nicholas', friends: ['Shelby', 'Court', 'Van']
};
let anotherPerson = Object.create(person, {    name: { value: 'Greg' }
});
alert(anotherPerson.name); //'Greg'

寄生式继承

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

function createAnother(original) {   let clone = Object.assign({}, original); //通过调用函数创建一个新对象   clone.sayHi = function () { //以某种方式来增强这个对象 alert('hi');  };  return clone; //返回这个对象
}

寄生组合式继承

前面说过,组合继承是JavaScript最常用的继承模式;不过,它也有自己的不足。组合继承最大的问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。没错,子类型最终会包含超类型对象的全部实例属性,但我们不得不在调用子类型构造函数时重写这些属性。再来看一看下面组合继承的例子。

function SuperType(name) {    this.name = name;  this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {    alert(this.name);
};
function SubType(name, age) {   SuperType.call(this, name); //第二次调用SuperType()  this.age = age;
}
SubType.prototype = new SuperType(); //第一次调用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {   alert(this.age);
};

有两组 name 和 colors 属性:一组在实例上,一组在 SubType 原型中。这就是调用两次 SuperType 构造函数的结果。好在我们已经找到了解决这个问题方法——寄生组合式继承。

所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下所示。

function SuperType(name) {   this.name = name;  this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {    console.log(this.name);
};
function SubType(name, age) {   SuperType.call(this, name); this.age = age;
}
SubType.prototype = Object.create(SuperType.prototype, { constructor: { value: SubType } })
SubType.prototype.sayAge = function () {   console.log(this.age);
};

这个例子的高效率体现在它只调用了一次 SuperType 构造函数,并且因此避免了在 SubType.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf() 。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

深入理解继承知识(下)相关推荐

  1. 计算机的来源知识,如何理解计算机知识及计算机发展史

    大家好,这里是链客区块链技术问答社区,今天讲一讲如何理解计算机知识,以及计算机的发展史.也感谢大家的关注~ 计算机是标准的理工科而不是文科,所以你要了解的不是它的历史,而是它最最基本的核心概念,以及后 ...

  2. [0 to 0.5]从零开始学习Android动画知识(下)

    [0 to 0.5]从零开始学习Android动画知识(下) 矢量动画(Scalable Vector Graphics) 不同于前面的为控件做动画效果的方法,矢量动画则是为图形做出动画效果 矢量图 ...

  3. 在人工智能领域,人工智能机器无法如人一样理解常识知识

    https://www.toutiao.com/a6664721599637225987/ 在人工智能领域,人工智能机器因为无法如人一样理解常识知识,而使人工智能机器表现出的智能程度极其有限. 因此, ...

  4. json 反序列化 父子类型_Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo...

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...

  5. C++继承体系下的对象构造

    继承体系下的对象构造 继承下的对象构造 虚拟继承 初始化"虚基类子对象" vptr的设置 总结 继承下的对象构造 class Point{public:Point(float x ...

  6. c++无继承情况下的对象构造

    无继承情况下的对象构造 C struct的Point声明 在C和C++中有什么区别? 抽象数据类型 包含虚函数的Point声明 自定义构造函数中会安插初始化vptr的代码 以成员为基础的赋值操作 C ...

  7. C++程序运行时内存布局之--无继承情况下的虚函数

    2019独角兽企业重金招聘Python工程师标准>>> 虚函数是C++实现多态的关键,没有虚函数,C++只能是OB,不能完成OO. 本文介绍的是没有继承情况下,带有虚函数的类在内存中 ...

  8. 绑定dictionary 给定关键字不再字典中_对字典嵌套的理解及二级下拉菜单的制作...

    大家好,今日我们继续讲解VBA数组与字典解决方案,今日讲解第51讲:对字典嵌套的理解及二级下拉菜单的制作. 在讲字典的时候,我反复说明,字典看视非常简单,由于它具有直达性可以省略去我们大量的循环查找代 ...

  9. matlab中的logspace,matlab中的logspace(a,b,n)究竟怎么理解,看下例题,谁能详细解给我看...

    matlab中的logspace(a,b,n)究竟怎么理解,看下例题,谁能详细解给我看 来源:互联网  宽屏版  评论 2009-12-07 10:11:30 分类: 教育/科学 >> 学 ...

最新文章

  1. 实践指南 | 用PyTea检测 PyTorch 中的张量形状错误
  2. linux gcc 显示/禁用 所有警告
  3. 自学python可以找到好的工作吗-通过自学python能找到工作吗
  4. 用计算机算出90除以6.28,用计算器计算:sin51°30′+ cos49°50′-tan46°10′的值是 .——青夏教育精英家教网——...
  5. 第二章:2.6 使用 runserver 命令把项目运行起来
  6. 剑指offer和LeetCode题目笔记
  7. Codeforces 976F
  8. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge
  9. CentOS7的yum安装mysql
  10. 【往届成功检索】ICAITA2020国际学术会议来袭,诚邀参与!
  11. java.sql.SQLException: null, message from server: “Host ‘xxx.xxx.xxx.xxx‘ is not allowed to
  12. 微信开发(1) -- 将本地开发环境映射到公网访问
  13. 特殊情形的Riemann引理
  14. sql convert 转换时间格式
  15. wps office 2019中文版
  16. 第三章 心剑,有妹紫灵
  17. 在XP IIS5.1手工安装PHP 5.2.11
  18. Payment:支付宝即时到账接口接入教程
  19. css 按空格键对按钮暂停,当按下回车键后,怎么清空回车键的空格,或者模拟发送按键让光标向上?...
  20. 元学习、迁移学习、对比学习、自监督学习与少样本学习的关系解读

热门文章

  1. 用 Python 训练自己的语音识别系统,这波操作稳了
  2. 华为发布政企战略及华为云Stack,瞄准新基建下政企的数字化转型
  3. 别人在加薪,你却在加班?快到这里和聪明的小伙伴一起充电吧!
  4. 扩容效率提升10倍,腾讯云发布一站式资源运维利器TIC
  5. 看我发现了什么好东西? Java Optional,绝对值得一学 | 原力计划
  6. 任正非:不赞成技术霸权争夺战;iPhone 7 被苹果划入“清仓产品”;Wine 4.18 发布 | 极客头条...
  7. 滴滴“负重”387天
  8. DOS 入侵、群发邮件、心脏起搏器……病毒攻击简史!
  9. 5G 2.0 的最新动向
  10. 简说 Python 生态系统的 14 年演变