JavaScript中的原型与原型链

时间:2021-05-01 14:34:55

  一直对JavaScript的原型与继承不了解,参考《JavaScript权威指南(第六版)》和《JavaScript高级程序设计(第三版)》对这个点的知识做个整理,方便自己记忆。以下内容大部分摘录自这两本书

每一个JavaScript对象都有与之相关的原型对象(prototype)。

原型对象有什么用?

  JavaScript对象会继承原型对象的属性。

原型对象是从哪里来的?

  首先我们先了解下创建对象基本的方式:

//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作为它们的原型对象;

  2.通过new创建的对象以构造函数的prototype属性作为原型对象

  3.通过Object.create()创建的对象使用第一个参数作为它们的原型对象;

  说明:任何函数都可以是构造函数,比如有一个函数F,当使用 var f=new F()创建对象时,F就是对象f的构造函数;其他情况下F就是一个普通的函数

除了通过Object.create()创建的对象的原型是我们自己指定的外,Object.prototype和构造函数的prototype属性又是怎么来的呢?

  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原型最简单的总结。请各路大侠批评指正!