一直对JavaScript的原型与继承不了解,参考《JavaScript权威指南(第六版)》和《JavaScript高级程序设计(第三版)》对这个点的知识作个整理,方便本身记忆。如下内容大部分摘录自这两本书前端
每个JavaScript对象都有与之相关的原型对象(prototype)。函数
JavaScript对象会继承原型对象的属性。this
首先咱们先了解下建立对象基本的方式:spa
//1,对象直接量 var a={},b={m:1} //2,构造函数 var c=new Object(),d=new Date(); //3,Object.create(param); var x=Object.create(d);
1.使用对象直接量建立的对象使用Object.prototype做为它们的原型对象;prototype
2.经过new建立的对象以构造函数的prototype属性做为原型对象;设计
3.经过Object.create()建立的对象使用第一个参数做为它们的原型对象;code
说明:任何函数均可以是构造函数,好比有一个函数F,当使用 var f=new F()建立对象时,F就是对象f的构造函数;其余状况下F就是一个普通的函数对象
除了经过Object.create()建立的对象的原型是咱们本身指定的外,Object.prototype和构造函数的prototype属性又是怎么来的呢?blog
1.Object.prototype是JavaScript内置的原型对象,定义了toString,valueOf等方法及一些属性。当咱们经过var a={}建立对象a,虽然咱们没有为a定义toString方法,可是当咱们调用a.toString()的时候会返回"[object Object]",这是由于这个方法已经在Object.prototype定义了。
继承
2.当咱们建立函数的时候,JavaScript就会为该函数建立一个prototype属性。请看代码:
function F(){} console.info(F.prototype);//{constructor: ƒ} console.info(F.prototype.constructor===F);//true
先了解一下JavaScript对象原型的例外,在JavaScript中有少数对象是没有原型对象的。
1.Object.prototype
2.null
3.经过Object.create(null)建立的对象;
除上述对象外,全部的JavaScript对象默认都有一个原型对象。原型对象也是一个对象实例,若是它不属于上述3类对象,那么它也有本身的原型对象。好比a的原型对象是b,b的原型对象是c,c的原型对象是d……直到遇到上述3类没有原型对象的对象,从而在a,b,c,d……之间构成了一个链,a-->b-->c-->d……,这就是原型链。
当在a中寻找一个属性,若是有返回属性值;若是没有就去b中找,有就返回属性值;若是没有就去c中找……,若是找到链的末端,还没找到就返回undefined。即经过原型链,实现了对象对原型链上的对象的继承。
说明:处在原型链前端的属性会隐藏后面对象的同名属性。好比:查找属性x,b和c中都有属性x,a.x的值等于b.x,而c中的x被隐藏了。
构造函数有默认的原型对象,这个原型对象的原型对象是Object.prototype。那么,经过new加构造函数建立对象,原型链上只会有三个对象,如何扩展这个原型链呢?请看代码:
//本段代码来自于《JavaScript高级程序设计(第三版)》163页
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //继承了 SuperType SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true
红色代码处,咱们修改了SubType函数的prototype属性的指向,使它指向了SuperType的一个对象实例。这个当咱们经过new SubType()建立对象instance时,instance的原型对象是SuperType实例,而SuperType实例的原型对象是SuperType.prototype,SuperType.prototype的原型对象是Object.prototype。这样咱们就扩展了对象instance的原型链。进而,咱们也能够把SuperType.prototype设置为别的对象实例而再次扩展原型链。以此类推,咱们能够无限扩展原型链。
能够看到经过原型链,能够在JavaScript中实现简单的继承:对象会继承本身原型链上的对象的属性。关于继承更进一步的知识请看《JavaScript高级程序设计(第三版)》6.3继承一节,讲的很详细。
以上就是对JavaScript原型最简单的总结。请各路大侠批评指正!