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

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

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

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

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

let p2 = object(p);

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

结果以下:程序员

这个效果和下面这种写法差很少web

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年)的做者。——维基百科

相关文章
相关标签/搜索