我知道一般情況下函數(shù)都是Function
的實(shí)例,例如:由function
關(guān)鍵字定義的函數(shù),一些內(nèi)置函數(shù),Array
、Number
、String
、Object
、Function
等等。還知道每一個(gè)函數(shù)都有一個(gè)prototype
屬性,一般情況下,fn.prototype
都是對(duì)象,但有個(gè)特例Function.prototype
var fn=function () {
console.log('hello')
}
fn instanceof Function //true
Array instanceof Function //true
Object instanceof Function //true
Function instanceof Function //true
typeof fn.prototype //"object"
typeof Array.prototype //"object"
typeof Object.prototype //"object"
但是typeof Function.prototype // "function"
既然是函數(shù),這個(gè)函數(shù)也是Function
創(chuàng)造的嗎?
Function.prototype instanceof Function //false
Function.prototype
這個(gè)函數(shù)為啥沒有prototype
屬性?不是每個(gè)函數(shù)都有嗎?
在chrome控制臺(tái)打印Function.prototype
是一個(gè)匿名函數(shù),想知道這個(gè)匿名函數(shù)是怎么來的?
Function.prototype 本身也是個(gè)函數(shù)對(duì)象,這是為了兼容 ES5。也估計(jì)是讓人引起誤解的源頭。但兩者還是不同的,這是個(gè)特殊的函數(shù)對(duì)象,它忽略參數(shù)總是返回 undefined,且沒有 [[Construct]] 內(nèi)部方法。
其實(shí)很容易理解,使用Function是這樣的
let f = new Funtion('x', 'return x')
那么再看下面的代碼
class _Function {
constructor (param, expression) {
this.param = param
this.expression = expression
}
}
let _f = new _Function('x', 'return x')
console.log(_Function.prototype) // _Function {}
console.log(_Function.prototype.prototype) // undefined
console.log(_Function.prototype.__proto__) // {}
console.log(Function.prototype) // [Function]
console.log(Function.prototype.prototype) // undefined
console.log(Function.prototype.__proto__) // {}
其實(shí),所有的對(duì)象的根不是 Object,而是 Object.prototype, 所有的函數(shù)的根不是 Function,而是 Function.prototype, 當(dāng)然 Function.prototype 的原型鏈上級(jí)還有 Object.prototype,所以才有 function 也是 Object 的表現(xiàn)。
所有函數(shù)都是 Function 的示例, 這句話沒有錯(cuò),但是我們通過這個(gè)標(biāo)識(shí)符拿到的,只是 Function 的構(gòu)造器,而造實(shí)例用的 “模子” 其實(shí)是 Function.prototype, 所以謂之原型也。我是這么理解的,所有的 function 都是 Function 用 Function.prototype 構(gòu)造出來的,F(xiàn)unction 本身是一個(gè)構(gòu)造器函數(shù),所以 Function 也是用 Function.prototype 構(gòu)造出來的。
instanceof
操作符的本質(zhì)其實(shí)是檢查原型鏈上是否有指定的原型,試著用函數(shù)實(shí)現(xiàn)一個(gè) instanceof :
function instanceOf(obj, Ctor) {
var proto = Object.getPrototypeOf(obj); // 獲得原型,等價(jià)于非標(biāo)準(zhǔn)的 __proto__
if(proto === null) return false; // 原型為null,到鏈的盡頭了
else if(proto === Ctor.prototype) return true; // 匹配到目標(biāo)原型對(duì)象
else return instanceOf(proto, Ctor); // 繼續(xù)探測(cè)原型本身是否是這個(gè)構(gòu)造器構(gòu)造的
}
instanceOf(Function, Function) // true,因?yàn)?Function.__proto__ === Function.prototype
從 JS 的視角看,在JS宿主(瀏覽器、NodeJS)創(chuàng)建世界之初,天地一片混沌(劃掉),JS的世界里沒有任何對(duì)象。第一個(gè)被捏出來的對(duì)象,是 Object.prototype,緊接著根據(jù) Object.prototype 為原型,宿主創(chuàng)建了 Function.prototype, Array.prototype 等一系列類型原型對(duì)象,這些 prototype 是構(gòu)造內(nèi)置對(duì)象的模子。接著這才開始用 Function.prototype 構(gòu)造出 Object、Function、Number、Array 和 Object.prototype.valueOf、Array.prototype.forEach 等一系列的 function 。
Function.prototype 才是第一個(gè)從 Object.prototype 下細(xì)分出來的函數(shù),和 Object.prototype/Array.prototype 一樣,它制定函數(shù)作為對(duì)象時(shí)長(zhǎng)什么樣,有哪些方法屬性。至于它本身,就是一個(gè)空函數(shù)而已,它也不是構(gòu)造器,不能用 new 來創(chuàng)造對(duì)象,它只是 new Function 的時(shí)候用來構(gòu)造實(shí)例的模子。
//function(){} 是 object 的原型層面解釋
Function.prototype instanceof Object // true
Function.prototype.__proto__ === Object.prototype // true
至于 typeof 對(duì) function 的區(qū)分,我也不大了解,可能對(duì)象在構(gòu)造之初就有一個(gè)內(nèi)部屬性追蹤其是否是一個(gè)函數(shù)吧,比如:
({__proto__:Function.prototype}) instanceof Function // true
typeof ({__proto__:Function.prototype}) // 然而 typeof 還是返回 object
({__proto__: Array.prototype}) instanceof Array // true
Array.isArray({__proto__: Array.prototype}) // Array.isArray 一下就認(rèn)出來這是一個(gè)假冒的array
所以 instanceof 操作符真的很單純,它只是檢查原型鏈而已。
其實(shí)令人困惑的是 Function/Object 這些引用本身即代表類型又代表類型的構(gòu)造器。
===========================
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問,美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。