文档章节

JavaScript继承(四)——原型式继承

Bob2100
 Bob2100
发布于 02/02 08:46
字数 825
阅读 51
收藏 1

道格拉斯·克罗克福特在2006年提出了原型式继承,他的想法是基于已有的对象借助原型创建新对象,同时还不必因此创建一个自定义类型。为此,他给出了下面的函数:

function object(obj){
  function F(){}
  F.prototype = obj;
  return new F();
}

object函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。其实本质还是原型链继承,只不过达到的效果是没有为新创建的对象单独声明一个类型,相当于简化版的原型链继承。来看下面具体的示例:

let p = {
  name: 'bob',
  friends: ['jack', 'rose']
}

let p2 = object(p);

console.log(p);
console.log(p2);

结果如下:

这个效果和下面这种写法差不多

let p2 = {};
p2.__proto__ = p;

console.log(p);
console.log(p2);

结果如下:

那为什么不直接使用这种方式呢?原因之一是直接操作对象的__proto__属性比较损耗浏览器的性能。

既然还是原型链继承,那么原型链继承的数据共享问题当然也是存在的,如下示例:

p2.friends.push('lily');
console.log(p.friends);//["jack", "rose", "lily"]
console.log(p2.friends);//["jack", "rose", "lily"]

更改了p2friends,导致pfriends也被更改了。

那么原型式继承的意义在哪儿呢?某些情况下只是简单地想让一个对象与另一个对象保持继承关系,没有必要兴师动众地先创建一个构造函数,这时原型式继承就派上用场了。实际上原型式继承如此好用,以致于ECMAScript标准委员会都看不下去了,在ECMAScript 5中通过新增Object.create()方法规范化了原型式继承。这个方法接收两个参数:一个用作新对象的原型,一个用于定义新对象的额外属性。在只传入一个参数的情况下,Object.create()object()效果相同。还是上面的示例,使用Object.create()创建p3,代码如下:

let p3 = Object.create(p);

结果如下:

传入两个参数,如下代码所示:

let p4 = Object.create(p, {
  name: {
    value: 'greg'
  }
});

结果如下:

所以以后想要使用原型式继承,调用Object.create()方法就可以了。

关于道格拉斯·克罗克福特:

道格拉斯·克罗克福特(英语:Douglas Crockford)是美国程序员和企业家,知名于对网页编程语言JavaScript推进和改良;且为轻量级数据交换格式“JSON”的创建者。他还是众多JavaScript语言开发工具的创造者,例如JSLint和JSMin。近段时间,他在PayPal担任JavaScript语言高级顾问,当然他也是JavaScript、JSON以及web技术的布道者,在这些方面出版发行了很多知名的书籍及演讲,是《JavaScript:语言精粹》(JavaScript: The Good Parts,2008年)的作者。——维基百科

© 著作权归作者所有

共有 人打赏支持
Bob2100
粉丝 23
博文 85
码字总数 46053
作品 0
浦东
高级程序员
私信 提问
JavaScript继承(五)——寄生式继承

首先回顾一下原型式继承: 寄生式继承是与原型式继承紧密相关的一种思路,并且同样也是由克罗克福德推而广之的。 说到寄生式继承不得不说工厂模式和寄生构造函数模式创建对象。下面来回顾一下...

Bob2100
02/13
0
0
JavaScript继承(六)——寄生组合式继承

JavaScript继承(三)——组合继承中讲到,组合继承是JavaScript中最常用的继承模式,但是它也有自己的不足之处,现在我们就来剖析它的不足,如下示例: 使用组合继承让继承实际上分为两步:...

Bob2100
02/16
0
0
JavaScript 中的继承:ES3、ES5 和 ES6

选择一种继承方式 JavaScript 是一门动态语言,动态意味着高灵活性,而这尤其可以体现在继承上面。JavaScript 中的继承有很多种实现方式,可以分成下面四类: Mixin 模式,即属性混入,从一个...

天方夜
2018/10/30
0
0
每个JavaScript工程师都应懂的33个概念

摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:stephentian Fundebug经授权转载,版权归原作者所有...

Fundebug
2018/10/30
0
0
JavaScript开发者应懂的33个概念

简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。 本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 ...

大灰狼的小绵羊哥哥
2018/10/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

设计模式-适配器模式

一、什么是适配器? 适配器就是一种适配中间件,将两种不匹配的东西进行适配连接,举一个生活中的例子。小金最近买了最新款的macbook pro,但是发现电脑的数据接口都变成了Type c接口,这导致...

kimyeongnam
9分钟前
0
0
在没有 Emacs 的情况下使用 Org 模式

每到年初似乎总有这么一个疯狂的冲动来寻找提高生产率的方法。新年决心,正确地开始一年的冲动,以及“向前看”的态度都是这种冲动的表现。软件推荐通常都会选择闭源和专利软件。但这不是必须...

linux-tao
22分钟前
0
0
Krpano skin_settings解释

<skin_settings maps="false" 是否显示地图按钮 maps_type="google" 地图类型 maps_bing_api_key="" bing地图授权key maps_google_......

华山猛男
23分钟前
0
0
兼容率达78%!首份Android Q版本兼容性评测报告出炉

据《Android Q Beta 1版本—国内主流千款典型应用兼容性测试数据评测报告》显示,该版本兼容率为78%。 那么,千款主流应用在Android Q版本兼容情况表现如何,不兼容的主要原因是什么,又将如...

安卓绿色联盟
25分钟前
1
0
二维数组排序

以二维数组$arr中apply_num为数字降序排列:array_multisort(array_column($arr,'apply_num'),SORT_DESC,SORT_NUMERIC,$arr);...

郭周园
30分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部