Javascript new關鍵字的玄機 以及其它

來源:互聯網
上載者:User

(接上)先看張對老手不新鮮但對菜鳥很有趣的圖:

    

What the heck is that? 簡直是luan lun。

new

拋開上面的圖,先看看上篇文章留下的第二個問題,讓我們在構造器的函數體內加點東西,看會發生什麼。

function A(){this.p = 1}
var a = new A()

會得到如下結果:

    

為什麼用new關鍵字構造出來的a,會獲得p這個屬性?new A()這行代碼做了什麼事情?根據上篇文章中Function的建立過程第4步,A這個對象會有一個Construct屬性(注意不是constructor,Consturct是ECMAScript標準裡的屬性,好像對外不可見),該屬性的值是個函數,new A()即會調用A的這個Construct函數。那麼這個Construct函數會做些啥呢?

  1, 建立一個object,假設叫x。

  2, 如果A.prototype是個object(一般都是),則把A.prototype賦給x.__proto__;否則(不常見),請大老闆Object出馬,把Object.prototype賦給x.__proto__。

  3, 調用A.call(x),第一個參數傳入我們剛剛建立的x。這就妥了,A的函數體裡this.p = 1,這個this,就成了x。因此x就有了p這個屬性,並且x.p = 1。

  4, 一般情況下,就返回x了,這時a就是x了。但也有特殊情況,如果A的函數體裡返回的東西,它的類型(typeof)是個object。那麼a就不是指向x了,而是指向A函數返回的東西。

虛擬碼如下:

var x = new Object(); //事實上不一定用new來建立,我也不清楚。
x.__proto__ = A.prototype
var result = A.call(x)
if (typeof(result) == "object"){
return result;
}
return x;

在我們的例子裡,A函數返回undefined(因為沒有return字眼),所以a就是x。但我們舉個例子,驗證下上面第4步裡的特殊情況:

    

果然。

對象的constructor屬性

再看看上篇文章留下的第一個問題

function Base(){}
Base.prototype.a = 1
var base = new Base();

function Derived(){}
Derived.prototype = base;
var d = new Derived()

執行完上面的代碼,mybase.constructor很容易猜到是Base,那麼d.constructor呢?是Derived嗎?

     

不對,也是Base,怎麼回事?很簡單,複習下上篇的內容就知道:由於d本身沒有constructor屬性,所以會到d.__proto__上去找,d.__proto__就是Derived.prototype,也就是base這個對象,base也沒constructor屬性,於是再往上,到base.__proto__上找,也就是Base.prototype。它是有constructor屬性的,就是Base本身。事實上,就我目前所知,只有構造器(function類型的object)的prototype,才真正自己擁有constructor屬性的對象,且“構造器.prototype.constructor === 構造器”。

Instanceof

那麼,instanceof怎麼樣?

    

可以看出,d是Base、Derived和Object的執行個體。很合理,但這是怎麼判斷的呢?是這樣的:對於x instanceof constructor的運算式,如果constructor.prototype在x的原型(__proto__)鏈裡,那麼就返回true。很顯然,d的__proto__鏈往上依次是:Derived.prototype, Base.prototype, Object.prototype,得到圖中結果就毫無疑問了。所以,instanceof跟對象的constructor屬性無關。

Function and Object

最後解答一下文章開頭的圖。

Function和Object本身也是function類型的對象,因此可以說都是Function()構造出來的東西(自己構造自己,我不知道具體是不是這樣,但就這麼認為,挺合理的。)

也就是說,可以設想如下代碼:

var Function = new Function()
var Object = new Function()

根據上篇文章的規律,會有Function.__proto__ === Function.prototype,以及Object.__proto__ === Function.prototype,驗證一下:

    

Function instanceof Object,這是顯然為true的,萬物歸Object管,Function的__proto__鏈依次指向:Function.prototype,Object.prototype。

Object instanceof Function,因為Function.prototype在Object的__proto__鏈中,所以也為true。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.