天天看點

Js中Prototype、__proto__、Constructor、Object、Function關系介紹總結

1 js的對象都擁有内部屬性 [[prototype]] 指向其原型對象。[[prototype]] 被稱為原型屬性。

2 内部屬性不可以直接通路.error: obj[[prototype]],但是可以間接通路 [[prototype]]

a ecma:标準對象原型通路器object.getprototype(object)(到目前為止隻有firefox和chrome實作了此通路器);

b 非标準通路器:__proto__(除了ie)

c obj.constructor.prototype

js的一切皆是對象,是以 函數也是對象.又因為對象擁有内部屬性 [[prototype]],是以

函數也擁有内部屬性 [[prototype]].

其次:函數同時擁有屬性 prototype.prototype屬性和 [[prototype]]并非同一個屬性。

prototype屬性指向一個對象,稱為原型對象。是以:一個函數的原型屬性(function’s prototype property ) 和函數實際的原型(prototype)沒有關系

原型對象的作用:當函數fn被用作構造函數時,其所建立的所有執行個體的内部屬性 [[prototype]] 指向 fn 的 prototype屬性。

原型的作用:

1 建構原型鍊

當對象調用某個方法時,如果其本身不存在此方法,就會往其原型中尋找,直到原型鍊的頂端

原型鍊的作用:多個執行個體都需要的方法可以被抽出放到原型中,進而隻需要定義一次,實作多個對象共享方法

js的所有對象都擁有constructor屬性,指向其構造函數。函數的原型對象也是對象,是以原型對象也擁有constructor屬性。并且js定下了規則:

即: 函數的prototype屬性的constructor字段,指向目前prototype屬性的擁有者,也就是構造函數本身

由 fn.prototype.constructor == fn;推導出來的結論:構造函數的執行個體的 constructor屬性 指向其構造函數

推導:

首先在a本身尋找:沒有找到 constructor屬性.再往原型鍊向上查找,找到a的原型,也就是 fn.prototype,發現了 constructor屬性。是以就相當于 構造函數的執行個體的 constructor屬性始終指向其構造函數

function、object:js自帶的函數對象

prototype,每一個函數對象都有一個顯示的prototype屬性,它代表了對象的原型(function.prototype函數對象是個例外,沒有prototype屬性)

__proto__:每個對象都有一個名為__proto__的内部隐藏屬性,指向于它所對應的原型對象(chrome、firefox中名稱為__proto__,并且可以被通路到)。原型鍊正是基于__proto__才得以形成(note:不是基于函數對象的屬性prototype)。

關于上面提到的函數對象,我們來看以下例子,來說明:

通常我們認為o1、o2是對象,即普通對象;f1、f2、f3為函數。但是其實函數也是對象,是由function構造的,f3這種寫法就跟對象的建立寫法一樣。f1、f2最終也都像f3一樣是有function這個函數構造出來的

f1、f2、f3為函數對象,function跟object本身也是函數對象

js中每個對象(null除外)都和另一個對象相關聯,通過以下例子跟記憶體效果圖來分析function、object、prototype、__proto__對象間的關系

通過上面代碼可以得出:

所有對象包括函數對象的原型鍊最終都指向了object.prototype,而<code>object.prototype.__proto__===null</code>,原型鍊至此結束。

animal.prototype是一個普通對象。

object是一個函數對象,也是function構造的,object.prototype是一個普通對象。

object.prototype.__type__指向null。

function.prototype是一個函數對象,前面說函數對象都有一個顯示的prototype屬性,但是function.prototype卻沒有prototype屬性,即function.prototype.prototype===undefined,所有function.prototype函數對象是一個特例,沒有prototype屬性

object雖是function構造的一個函數對象,但是object.prototype沒有指向function.prototype,即object.prototype!==function.prototype

在 javascript 中,每個函數對象都有名為“prototype”的屬性(上面提到過function.prototype函數對象是個例外,沒有prototype屬性),用于引用原型對象。此原型對象又有名為“constructor”的屬性,它反過來引用函數本身。這是一種循環引用(i.e. animal.prototype.constructor===animal)

constructor 屬性是專門為 function 而設計的,它存在于每一個 function 的prototype 屬性中。這個 constructor 儲存了指向 function 的一個引用

注意:object.constructor===function;本身object就是function函數構造出來的

如何查找一個對象的constructor,就是在該對象的原型鍊上尋找碰到的第一個constructor屬性所指向的對象

為什麼 xx.constructor.prototype 可以通路到目前對象的原型。

'str'.constructor.prototype

'str'.constructor 指向目前對象的構造函數

(構造函數).prototype:即函數的prototype 屬性

1) 函數有prototype屬性,是以可以通路到

2) 函數的prototype屬性會在建立執行個體的時候作為執行個體的原型而存在。

是以 'str'.constructor.prototype 就可以通路到目前對象執行個體的原型。

'str'.constructor == string

true.constructor == boolean

(1).constructor == number

{}.constructor == object

[].constructor == array

function(){}.constructor == function

result:全部都是:function function(){}

推論:内置對象的構造器,全部都是 <code>function function(){}</code>,包括function本身。是以js所有的内置對象的構造器都是 <code>function function(){}</code>

2.

number.__proto__ === function.prototype // true

boolean.__proto__ === function.prototype // true

string.__proto__ === function.prototype // true

object.__proto__ === function.prototype // true

function.__proto__ === function.prototype // true

array.__proto__ === function.prototype // true

regexp.__proto__ === function.prototype // true

error.__proto__ === function.prototype // true

date.__proto__ === function.prototype // true

function.prototype.__proto__ == object.prototype

object.prototype.__proto__ == object.prototype

number.prototype.__proto__ == object.prototype

boolean.prototype.__proto__ == object.prototype

string.prototype.__proto__ == object.prototype

array.prototype.__proto__ == object.prototype

regexp.prototype.__proto__ == object.prototype

error.prototype.__proto__ == object.prototype

date.prototype.__proto__ == object.prototype

推論:隻有函數才有 prototype屬性,是以上面的 xxx.prototype 中的xxx都是構造函數,又有2中的 xxx.__proto__。是以:xxx既可以是内置對象,也可以是構造函數。根據情景判斷。object的所有執行個體的原型都是 object.prototype

object.constructor == function

function.prototype.__proto__ == object.prototype;

并且:object.prototype.__proto__ == null;

繼續閱讀