1. 程式人生 > >js--3.物件-10.原型函式

js--3.物件-10.原型函式

1      原型物件

1.1  理解概念

在建構函式中存在著一個名為原型的(prototype)物件,相當於一個公共的區域,所有同一個類的例項都可以訪問到這個原型物件,我們可以將物件中共有的內容,統一設定到原型物件中。

以後我們建立建構函式時,可以將這些物件共有的屬性和方法,統一新增到建構函式的原型物件中,這樣不用分別為每一個物件新增,也不會影響到全域性作用域,就可以使每個物件都具有這些屬性和方法了,凡是通過該建構函式建立的物件都可以訪問存在於原型中的屬性。

1.2  獲得原型物件

原型就是一個物件,和其他物件沒有任何區別,可以通過建構函式來獲取原型物件。

–建構函式. Prototype

除了可以通過建構函式獲取原型物件以外,還可以通過具體的物件來獲取原型物件。

1.Object.getPrototypeOf(物件)

2.物件.__proto__

3.物件.constructor.prototype

需要注意的是,我們可以獲取到Object的原型物件,也可以對它的屬性進行操作,但是我們不能修改Object原型物件的引用。 

1.3  原型中新增屬性和方法

和其他物件一樣我們可以新增修改刪除原型中的屬性,也可以修改原型物件的引用。

  

2      原型繼承

2.1  理解概念

一切(引用型別)都是物件,物件是屬性的集合

物件都是通過函式來建立的

函式都有(不是隻有)一個屬性叫做prototype。其的屬性值是一個物件,預設的只有一個叫做constructor的屬性,指向這個函式本身。

每個物件都有一個__proto__屬性,指向建立該物件的函式的prototypeObject.prototype確實一個特例——它的__proto__指向的是null,切記切記

2.2  函式物件中的prototype

2.2.1  普通物件--constructor

    我們所建立的每一個函式,解析器都會向函式中新增一個屬性prototype(原型), 這個prototype的屬性值是一個物件,預設的只有一個叫做constructor的屬性,指向這個函式本身。需要注意的是prototype屬性只存在於函式物件中。

 

即,Fn是一個函式,fn物件是從Fn函式new出來的,這樣fn物件就可以呼叫Fn.prototype中的屬性。

2.2.2  Object物件

原型既然作為物件,屬性的集合,不可能就只弄個constructor來玩玩,肯定可以自定義的增加許多屬性。例如這位Object大哥,人家的prototype裡面,就有好幾個其他屬性。

 

2.3  物件中的__proto__

2.3.1  建構函式物件中的__proto__

    如果函式作為普通函式呼叫prototype沒有任何作用

    當函式以建構函式的形式呼叫時,它所建立的物件中都會有一個隱含的屬性,指向該建構函式的原型物件,我們可以通過__proto__來訪問該屬性

2.3.2       Object原型物件的__proto__

每一個物件都有原型,包括原型物件也有原型。特殊的是Object的原型物件沒有原型。

 

2.4  注意

2.4.1  obj.__proto__與Object.prototype

obj這個物件本質上是被Object函式建立的,因此obj.__proto__===Object.prototype

 

3      原型鏈

3.1  原型鏈

基於我們上邊所說的,每個物件都有原型物件,原型物件也有原型物件。由此,我們的物件,和物件的原型,以及原型的原型,就構成了一個原型鏈。

         比如這麼一個物件:varmc = new MyClass(123,456);

原型鏈的次序是:mc物件、mc物件的原型物件、原型物件的原型(Object)、Object的原型

 

3.2  原型鏈查詢

原型物件也是物件,所以它也有原型,

1.當我們使用一個物件的屬性或方法時,會現在自身中尋找,自身中如果有,則直接使用,

    2.如果沒有則去原型物件中尋找,如果原型物件中有,則使用,

    3.如果沒有則去原型的原型中尋找,直到找到Object物件的原型,

    Object物件的原型沒有原型,如果在Object原型中依然沒有找到,則返回undefined

 

3.3  instanceof

判斷一個變數是不是物件非常簡單。值型別的型別判斷用typeof,引用型別的型別判斷用instanceof。instanceof表示的就是一種繼承關係,或者原型鏈的結構

語法:var result = 變數instanceof 型別

Instanceof的判斷隊則是:沿著A的__proto__這條線來找,同時沿著B的prototype這條線來找,如果兩條線能找到同一個引用,即同一個物件,那麼就返回true。如果找到終點還未重合,則返回false。

 

3.4  hasOwnProperty()

可以使用物件的hasOwnProperty()來檢查物件自身中是否含有該屬性,使用該方法只有當物件自身中含有屬性時,才會返回true;在查詢f1.hasOwnProperty屬性時,就會順著原型鏈一直查詢到Object.prototype。

 

3.5  toString(瞭解)

最典型的原型中的屬性就是toString()函式,實際上我們的物件中並沒有定義這個函式,但是卻可以呼叫,那是因為這個函式存在於Object對應的原型中。

當我們直接在頁面中列印一個物件時,事件上是輸出的物件的toString()方法的返回值,如果我們希望在輸出物件時不輸出[objectObject],可以為物件新增一個toString()方法