[笔记][JavaScript]物件间基本的原型链(1)

两个物件间的原型关係和继承有关,每个物件都可以有另一个物件做为他的原型,如此一来,前者就会继承后者的所有特性。

如果要为物件指定「原型」,可以使用物件函式Object.create()Object.setPrototypeOf()来指定另外一个物件来当做「原型」,而藉由此方式串起来的多个物件也被称做「原型链」。

这一篇先讲建立物件并指定原型的方式,物件函式Object.create()有两个参数,第一个是为物件指定原型,第二个为建立特性。

以下做个为物件指定原型的简单範例

//建立a物件var objA = {    writeName:function(){        return 'Name is ' + this.name;    },};//建立b物件并指定原型物件为objA(第一个参数)//设定一个可变(writable:true)特性给objB,并指定值为'B'var objB = Object.create(objA,{    name:{value:'B',writable:true}});//此时objB会继承objA的所有特性(继承特性),也包含了自己的特性(自有特性)objB.writeName(); //会回传'Name is B'//objB的自有特性name值也可以被更改objB.name='renameB'objB.writeName(); //会回传'Name is renameB'//而被继承而来的特性是无法被移除的delete objB.writeName; //会回传ture,但该特性不会被移除objB.writeName(); //会回传'Name is renameB'//但是在Object.create中指定的原型和特性不会被Object.keys()所读到Object.keys(objB); //会得到空的阵列[],不会取得任何键值//如果我们在objB上新增一个和objA物件中的writeName同名特性objB.writeName=function(){        return 'objBName is ' + this.name;};//他会以自有特性为主,如果自有特性没有该键值才会向原型寻找特性objB.writeName(); //会回传'objBName is renameB'//因为刚刚指定writeName特性,所以Object.keys()就可以读到了Object.keys(objB); //会得到["writeName"]//这时候我们再来移除objB的writeName特性看看delete objB.writeName; //会回传ture,然后把objB的自有特性writeName移除//在呼叫时就会向原型寻找到objA的特性objB.writeName(); //会回传'Name is renameB'

以上是一种指定原型的方式,但要为了新宣告的物件指定特性的方式太麻烦了,所以我们通常会只建立一个指定原型的物件,之后再来手动建立特性。

//先建立一个指定原型为物件B的新物件var objC = Object.create(objB);//之后在手动加入特性objC.age=20;//手动建立的特性就可以被Object.keys()取得,但继承而来的键值依旧不会显示Object.keys(objC); //会回传["age"]//而因为他继承自objB,objB又继承自objA,所以objC会同时有这两个物件的特性objC.writeName(); //会回传'Name is renameB'

由上面的範例可以知道经过继承的物件会有「原型」、「自有特性」、「继承特性」这三种,那我们要如何读取一个物件的这些资讯呢?

首先我们用Object.getPrototypeOf()来呼叫原型物件。

Object.getPrototypeOf(objC); //会回传objB的物件内容Object.getPrototypeOf(objC) === objB //回传true,因为他直接回传objB的物件,所以两个是相等的//其实物件内还有一个特殊特性__proto__他也可以直接取得该物件的原型objC.__proto__ === objB //回传true//也有函式可以直接检查一个物件与另一个物件是否有在相同的原型链上Object.isPrototypeOf(obj);//来试着判断objB是否为objC的原型objB.isPrototypeOf(objC); //会回传trueobjA.isPrototypeOf(objC); //因为objA是objB的原型,objB又是objC的原型,两人在同一个原型链上,所以回传trueobjC.isPrototypeOf(objB); //虽然两者在同一个原型链上,但objC不是objB的原型,所以回传false

要检查是否含有某个「自有特性」的键值,可以使用hasOwnProperty()

//检查objC物件中是否含有键值为age的自有特性objC.hasOwnProperty('age'); //会回传true//检查objC物件中是否含有键值为writeName的自有特性objC.hasOwnProperty('name'); //会回传false,因为name是属于原型objB的特性

最后如果要检查该特性是否包含某个「继承特性」可以直接用in,这做法对「自有特性」或「继承特性」都有效。

'name' in objC; //就算'name'是继承自原型objB的特性,还是会回传true'writeName' in objC; //就算是原型的原型物件的特性,还是会回传true'age' in objC; //自有特性也会回传true

以上是创建新物件并指定原型物件的各种方式,还有一些关于原型的物件函式操作,如果有说明错误或不明白的地方,麻烦再留言告知我,我会尽速改正!!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章