昨天有提到说Object.setPrototypeOf可以指定一个物件为另一个物件的原型,但有想过到底这个原型,也就是[[Prototype]]最终会到何处吗?

答案是Object.prototype!

 

Object.prototype

在第一天有提到说「JS中除了原始型别以外的一切都是物件」。

 

所以每条正常的[[Prototype]]串链最顶层的尾端都是内置的Object.setPrototypeOf,这个物件含有JS中各地方所用的常见工具,如toString()、hasOwnProperty()、valueOf()等等,所有正常的物件都应起源于这个Object.setPrototypeOf物件(vmwork)。

 

建构式与原型

在第八天时,有提到说建构式会经由new呼叫函式,建立一个新的物件:

 

function Foo(){

this.say =“hello”;

}

var a = new Foo();

但其实new Foo()产生一个新的物件a同时,新的物件a的内部会有[[Prototype]]连接至Foo.prototype。

等等,Foo.prototype的.prorotype是什么鬼东西?函式有自己的原型?

 

「每一个函式都有一个原型物件,会被自动设为透过该函式所建立的物件原型」。

也就是说prototype是当用new创建新的物件时,该新物件的[[Prototype]]。

 

那我们要怎么看一个物件的原型呢?可以用__proto__或Object.getPrototypeOf()。

 

function Foo(){

this.say =“hello”;

}

var a = new Foo();

 

a.__proto__;//{constructor:ƒ}

Object.getPrototypeOf(a);//{constructor:ƒ}

 

Object.getPrototypeOf(a)=== Foo;//false

Object.getPrototypeOf(a)=== Foo.prototype;//true

用图表来看可能会比较好理解。

 


好,又有一个奇怪的东西了,什么是constructor?

函式的原型物件也就是Foo.prototype会具有constructor的属性,会参照回原来的函式。

我们建立出来的新物件,其原型会被设定为建构式函式原型所参照的物件,可以透过.constructor来存取建立物件的函式以此来作类型检查。

 

function Foo(){

this.say =“hello”;

}

var a = new Foo();

 

typeof a;//“object”

a instanceof Foo;//true

a.constructor === Foo;//true

a.__proto__.constructor === Foo;//true

所以我们可以用这张图来表示。

 


使用原型来实现继承

函式原型是一个物件,所以在继承实有许多种复制功能的方式。

 

function Person(){};

Person.prototype.say =“Hi”;

 

function trickyMan(){};

trickyMan.prototype = { say:Person.prototype.say};

 

var Jason = new trickyMan();

 

Jason instanceof trickyMan;//true

Jason instanceof Person;//false

执行后发现没有办法把Person继承trickyMan,这只是复制而已。

如果想要真正的原型串链,也就是Jason可以是trickyMan,trickyMan可以是Person,一直到最终的Object,应该这样做:

 

function Person(){};

Person.prototype.say =“Hi”;

 

function trickyMan(){};

trickyMan.prototype = new Person();

 

var Jason = new trickyMan();

 

Jason instanceof trickyMan;//true

Jason instanceof Person;//true

要注意到的是,由于把trickyMan指定为Person的建构物件,所以trickyMan的原本的constructor没有被任何东西参考,会被弃置且删除。

我们来看一下图片(leafor)。

那么,今天就到这边,一样如果有错误及来源未附上也欢迎留言指正,那么我们明天见。