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__屬性,指向建立該物件的函式的prototype。Object.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()方法