Javascript new關(guān)鍵字的玄機(jī) 以及其它
(接上)先看張對(duì)老手不新鮮但對(duì)菜鳥很有趣的圖:
What the heck is that? 簡(jiǎn)直是luan lun。
new
拋開上面的圖,先看看上篇文章留下的第二個(gè)問題,讓我們?cè)跇?gòu)造器的函數(shù)體內(nèi)加點(diǎn)東西,看會(huì)發(fā)生什么。
function A(){this.p = 1}
var a = new A()
會(huì)得到如下結(jié)果:
為什么用new關(guān)鍵字構(gòu)造出來(lái)的a,會(huì)獲得p這個(gè)屬性?new A()這行代碼做了什么事情?根據(jù)上篇文章中Function的創(chuàng)建過(guò)程第4步,A這個(gè)對(duì)象會(huì)有一個(gè)Construct屬性(注意不是constructor,Consturct是ECMAScript標(biāo)準(zhǔn)里的屬性,好像對(duì)外不可見),該屬性的值是個(gè)函數(shù),new A()即會(huì)調(diào)用A的這個(gè)Construct函數(shù)。那么這個(gè)Construct函數(shù)會(huì)做些啥呢?
1, 創(chuàng)建一個(gè)object,假設(shè)叫x。
2, 如果A.prototype是個(gè)object(一般都是),則把A.prototype賦給x.__proto__;否則(不常見),請(qǐng)大老板Object出馬,把Object.prototype賦給x.__proto__。
3, 調(diào)用A.call(x),第一個(gè)參數(shù)傳入我們剛剛創(chuàng)建的x。這就妥了,A的函數(shù)體里this.p = 1,這個(gè)this,就成了x。因此x就有了p這個(gè)屬性,并且x.p = 1。
4, 一般情況下,就返回x了,這時(shí)a就是x了。但也有特殊情況,如果A的函數(shù)體里返回的東西,它的類型(typeof)是個(gè)object。那么a就不是指向x了,而是指向A函數(shù)返回的東西。
偽代碼如下:
var x = new Object(); //事實(shí)上不一定用new來(lái)創(chuàng)建,我也不清楚。
x.__proto__ = A.prototype
var result = A.call(x)
if (typeof(result) == "object"){
return result;
}
return x;
在我們的例子里,A函數(shù)返回undefined(因?yàn)闆]有return字眼),所以a就是x。但我們舉個(gè)例子,驗(yàn)證下上面第4步里的特殊情況:
果然。
對(duì)象的constructor屬性
再看看上篇文章留下的第一個(gè)問題
function Base(){}
Base.prototype.a = 1
var base = new Base();
function Derived(){}
Derived.prototype = base;
var d = new Derived()
執(zhí)行完上面的代碼,mybase.constructor很容易猜到是Base,那么d.constructor呢?是Derived嗎?
不對(duì),也是Base,怎么回事?很簡(jiǎn)單,復(fù)習(xí)下上篇的內(nèi)容就知道:由于d本身沒有constructor屬性,所以會(huì)到d.__proto__上去找,d.__proto__就是Derived.prototype,也就是base這個(gè)對(duì)象,base也沒constructor屬性,于是再往上,到base.__proto__上找,也就是Base.prototype。它是有constructor屬性的,就是Base本身。事實(shí)上,就我目前所知,只有構(gòu)造器(function類型的object)的prototype,才真正自己擁有constructor屬性的對(duì)象,且“構(gòu)造器.prototype.constructor === 構(gòu)造器”。
Instanceof
那么,instanceof怎么樣?
從圖中可以看出,d是Base、Derived和Object的實(shí)例。很合理,但這是怎么判斷的呢?是這樣的:對(duì)于x instanceof constructor的表達(dá)式,如果constructor.prototype在x的原型(__proto__)鏈里,那么就返回true。很顯然,d的__proto__鏈往上依次是:Derived.prototype, Base.prototype, Object.prototype,得到圖中結(jié)果就毫無(wú)疑問了。所以,instanceof跟對(duì)象的constructor屬性無(wú)關(guān)。
Function and Object
最后解答一下文章開頭的圖。
Function和Object本身也是function類型的對(duì)象,因此可以說(shuō)都是Function()構(gòu)造出來(lái)的東西(自己構(gòu)造自己,我不知道具體是不是這樣,但就這么認(rèn)為,挺合理的。)
也就是說(shuō),可以設(shè)想如下代碼:
var Function = new Function()
var Object = new Function()
根據(jù)上篇文章的規(guī)律,會(huì)有Function.__proto__ === Function.prototype,以及Object.__proto__ === Function.prototype,驗(yàn)證一下:
Function instanceof Object,這是顯然為true的,萬(wàn)物歸Object管,F(xiàn)unction的__proto__鏈依次指向:Function.prototype,Object.prototype。
Object instanceof Function,因?yàn)镕unction.prototype在Object的__proto__鏈中,所以也為true。
- JavaScript定義數(shù)組的三種方法(new Array(),new Array(''x'',''y'')
- javascript中new關(guān)鍵字詳解
- 詳解Javascript中new()到底做了些什么?
- javascript new一個(gè)對(duì)象的實(shí)質(zhì)
- js中new一個(gè)對(duì)象的過(guò)程
- JavaScript中的new的使用方法與注意事項(xiàng)
- 詳解javascript new的運(yùn)行機(jī)制
- javascript new 需不需要繼續(xù)使用
- JavaScript中實(shí)現(xiàn)new的兩種方式引發(fā)的探究
相關(guān)文章
JS+CSS實(shí)現(xiàn)TreeMenu二級(jí)樹形菜單完整實(shí)例
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)TreeMenu二級(jí)樹形菜單,以完整實(shí)例形式較為詳細(xì)的分析了JS二級(jí)樹形菜單的節(jié)點(diǎn)元素操作技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-09-09點(diǎn)擊彈出層效果&彈出窗口后網(wǎng)頁(yè)背景變暗效果的實(shí)現(xiàn)代碼
本篇文章主要是對(duì)點(diǎn)擊彈出層效果&彈出窗口后網(wǎng)頁(yè)背景變暗效果的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02獲取元素距離瀏覽器周邊的位置的方法getBoundingClientRect
本文為大家介紹下如何使用getBoundingClientRect()方法獲取元素距離瀏覽器周邊的位置,有類似問題的朋友可以參考下哈,希望對(duì)你學(xué)習(xí)js有所幫助2013-04-04JavaScript實(shí)現(xiàn)的購(gòu)物車效果可以運(yùn)用在好多地方
JavaScript實(shí)現(xiàn)的購(gòu)物車效果,當(dāng)然這個(gè)效果可以運(yùn)用在好多地方,比如好友的選擇,人力資源模塊等等,需要的朋友可以參考下2014-05-05JS實(shí)現(xiàn)將圖片轉(zhuǎn)為base64格式
Base64是一種用64個(gè)字符來(lái)表示任意二進(jìn)制數(shù)據(jù)的方法,這篇文章主要為大家介紹了如何實(shí)現(xiàn)將圖片轉(zhuǎn)為base64格式,感興趣的小伙伴可以學(xué)習(xí)一下2023-07-07js RuntimeObject() 獲取ie里面自定義函數(shù)或者屬性的集合
取得ie 里面 自定義函數(shù)或者屬性的集合 使用RuntimeObject()實(shí)現(xiàn),需要的朋友可以參考下。2010-11-11javascript中的undefined 與 null 的區(qū)別 補(bǔ)充篇
在Javascript中有兩個(gè)值用來(lái)代表類似空值的概念,undefined和null,這兩個(gè)很容易被混淆,他們表示的是兩個(gè)不同的概念。2010-03-03