JavaScript中Function與Object的關(guān)系
原型鏈
我們來(lái)回顧一下什么是原型
我們知道js中所有的對(duì)象、函數(shù)、數(shù)組都可以看成對(duì)象,也就是一切皆是對(duì)象
所有的對(duì)象身上都有一個(gè)
__proto__
屬性,他叫隱式原型,指向了構(gòu)造這個(gè)對(duì)象(如obj)的構(gòu)造函數(shù)(例如Constructor)的原型對(duì)象即Constructor.prototype,也就是說(shuō)obj.__proto__===Constructor.prototype
,這兩個(gè)指針指向的其實(shí)是同一塊堆空間在構(gòu)造函數(shù)的原型對(duì)象prototype(
Constructor.prototype
)中,一般包含constructor
屬性和__proto__
屬性。其中
constructor
包含函數(shù)的一些信息如argments
、caller
、length
、name
和prototype指向構(gòu)造函數(shù)的原型對(duì)象自身以及__scope__
即閉包屬性(其中有函數(shù)需要使用的外部變量以及全局上下文,以偽數(shù)組的形式儲(chǔ)存在scope閉包對(duì)象中),另外__proto__
的話(huà),其實(shí)就是把Constructor.prototype
看成new
出來(lái)的對(duì)象實(shí)例,__proto__
就是指向Constructor.prototype
的構(gòu)造函數(shù)(如Superconstructor
)的實(shí)例對(duì)象即Superconstructor.prototype
具體可以參照下圖:
然后是原型鏈
由于對(duì)象(如obj)的隱式原型(
obj.__proto__
)指向構(gòu)造函數(shù)的prototype
(如Constructor.prototype
),而這個(gè)
prototype
(如Constructor.prototype
)里面又有一個(gè)__proto__
,它指向了prototype
的構(gòu)造函數(shù)的prototype
(如Superconstructor.prototype
),然后
Superconstructor.prototype.__proto__
指向了Object.prototype
這樣就形成了一個(gè)簡(jiǎn)單的鏈?zhǔn)浇Y(jié)構(gòu),這個(gè)條鏈的最后是
Object.prototype.__proto__
為null
以上就是原型鏈的構(gòu)成
原型鏈的使用
當(dāng)你使用一個(gè)對(duì)象的屬性或方法時(shí),會(huì)先在該對(duì)象上查找已有屬性,如果沒(méi)有,就找到__proto__,找原型身上的屬性,如果原型沒(méi)有,那就再找原型的原型身上是否存在待查找屬性,知道找到或者找到原型鏈的頂端null
關(guān)于原型鏈一些有意思的東西
我們知道typeof
可以用于判斷變量的數(shù)據(jù)類(lèi)型,但是對(duì)于復(fù)雜數(shù)據(jù)類(lèi)型,它只能判斷出對(duì)象、數(shù)組或函數(shù),這對(duì)于我們的使用來(lái)說(shuō)是不夠的
所以我們可以用instanceof
來(lái)判斷引用數(shù)據(jù)類(lèi)型的對(duì)象類(lèi)型
typeof A //'function' obj instanceof A //true obj instanceof Object //true
在使用時(shí)我發(fā)現(xiàn)一個(gè)有趣的問(wèn)題
Function instanceof Object //true Object instanceof Function //true
這是為什么呢?
我們嘗試使用
Function.__proto__===Object.prototype //false
發(fā)現(xiàn)得到的是false,也就是Function并不是Object new出來(lái)的
但是嘗試
Object.__proto__===Function.prototype //true
卻發(fā)現(xiàn)Object是由Function new
出來(lái)的
接著我們分析一下instanceof
的工作原理, 我們嘗試用函數(shù)instance_of來(lái)手寫(xiě)instanceof
關(guān)鍵字
function instance_of(L, R) { var O = R.prototype; L = L.__proto__; while (true) { if (L === null) return false; if (O === L) return true; L = L.__proto__; } }
對(duì)于以上代碼分析,我們其實(shí)是在找左值的原型鏈上是否存在右值的原型
于是我們嘗試
Function.__proto__===Function.prototype //true Function.__proto__.__proto__===Object.prototype //true
發(fā)現(xiàn)原來(lái)Function.prototype
是由Object new
出來(lái)的,同時(shí)Function也是可以由自己new
出來(lái)
- 綜上,
Function
由Functionnew出來(lái)
,Object
由Functionnew
出來(lái),Function.prototype
由Objectnew
出來(lái)
最后是關(guān)于new關(guān)鍵字
當(dāng)代碼 new Foo(...)
執(zhí)行時(shí),會(huì)發(fā)生以下事情:
- 一個(gè)繼承自
Foo.prototype
的新對(duì)象被創(chuàng)建(類(lèi)似于Object.create
)。 - 使用指定的參數(shù)調(diào)用構(gòu)造函數(shù)
Foo
,并將this
綁定到新創(chuàng)建的對(duì)象。new Foo
不帶括號(hào)就是沒(méi)有指定參數(shù)列表,Foo
不帶任何參數(shù)調(diào)用。 - 由構(gòu)造函數(shù)返回對(duì)象,作為
new
表達(dá)式的結(jié)果。如果構(gòu)造函數(shù)沒(méi)有顯式返回一個(gè)對(duì)象,則使用步驟 1 創(chuàng)建的對(duì)象。(一般情況下,構(gòu)造函數(shù)不返回值,但是可以選擇主動(dòng)返回對(duì)象,來(lái)覆蓋正常的對(duì)象創(chuàng)建步驟)
嘗試用newFun
手寫(xiě)new
關(guān)鍵字
function newFun(Constructor) { var obj = {}; obj.__proto__ = Constructor.prototype; return Constructor.apply(obj); };
使用Object.create
function newFun() { Constructor = [].shift.call(arguments);// 取出第一個(gè)參數(shù)Constructor var obj = Object.create(Constructor); return Constructor.apply(obj, arguments);// 使用參數(shù)調(diào)用 };
- 補(bǔ)充一點(diǎn)題外話(huà)使用對(duì)象鏈?zhǔn)秸{(diào)用hh()函數(shù),它的this指向通過(guò)隱式綁定還是指向直接調(diào)用它的對(duì)象a,而不是間接調(diào)用的對(duì)象b
let a = { k:10, hh(){ console.log(this); } } let b = { k:9, a } b.a.hh();
到此這篇關(guān)于JavaScript中Function與Object的關(guān)系的文章就介紹到這了,更多相關(guān)JavaScript Function Object內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- javascript中的 object 和 function小結(jié)
- JavaScript中Function函數(shù)與Object對(duì)象的關(guān)系
- 淺談Javascript中Object與Function對(duì)象
- 淺談Javascript中的Function與Object
- 理解Javascript_09_Function與Object
- 驗(yàn)證javascript中Object和Function的關(guān)系的三段簡(jiǎn)單代碼
- javascript Object與Function使用
- JavaScript中Object和Function的關(guān)系小結(jié)
相關(guān)文章
JavaScript數(shù)據(jù)結(jié)構(gòu)之雙向鏈表定義與使用方法示例
這篇文章主要介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)之雙向鏈表定義與使用方法,簡(jiǎn)單介紹了雙向鏈表的原理,并結(jié)合實(shí)例形式分析了雙向鏈表的定義與使用方法,需要的朋友可以參考下2017-10-10JS中簡(jiǎn)單的實(shí)現(xiàn)像C#中using功能(有源碼下載)
JS中簡(jiǎn)單的實(shí)現(xiàn)像C#中using功能(有源碼下載)...2007-01-01Bootstrap modal 多彈窗之疊加顯示不出彈窗問(wèn)題的解決方案
Bootstrap modal 多彈窗之疊加顯示不出彈窗問(wèn)題,今天小編抽時(shí)間給大家分享下解決方案,需要的朋友參考下2017-02-02JavaScript中SetInterval與setTimeout的用法詳解
在寫(xiě)H5游戲時(shí)經(jīng)常需要使用定時(shí)刷新頁(yè)面實(shí)現(xiàn)動(dòng)畫(huà)效果,比較常用即setTimeout()以及setInterval(),但是大家對(duì)SetInterval與setTimeout的用法了解嗎,下面通過(guò)本文給大家詳解js中SetInterval與setTimeout的用法,需要的朋友參考下2015-11-11JavaScript實(shí)現(xiàn)頁(yè)面5秒后自動(dòng)跳轉(zhuǎn)的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)頁(yè)面5秒后自動(dòng)跳轉(zhuǎn)的方法,涉及javascript遞歸調(diào)用與計(jì)時(shí)函數(shù)setTimeout的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04