javascript中的null,對象系統還是非對象系統?


1.一直以來的認知

在我學習js的過程中,愛民老師的綠皮書里將js的類型系統分成了兩類:

其一是元類型系統:由typeof運算來檢測

其二是對象類型系統:是元類型的object的一個分支

而null這個關鍵字也被歸類到了對象類型系統里面了:

  • 是屬於對象系統的
  • 對象是空值

所以,當我們使用typeof去考察Null的話,會返回給我們"object"。

如果去用for(... in  null)的方式試圖去枚舉Null里面的屬性的時候。ES5會先行判斷null和undefined,如果是這兩個值的話,不會去執行循環體。

而我認為這一切都是null既無屬性也無方法導致的。而且null也並無原型,也並不是Object()構造器或者其子類實例而來的。

而我是c#出身的前端,我覺得將null歸類到對象系統里面是一個不錯的選擇!

 

2.《你不知道的js》里面怎么說的?

當我看到第三章的對象的時候,里面有這樣一段話

null 有時會被當作一種對象類型,但是這其實只是語言本身的一個 bug,即對 null 執行
typeof null 時會返回字符串 "object"。實際上,null 本身是基本類型

看到這里,完全顛覆我的認知啊!

按照“u dot know”里面的划分的話其實也是書里面很常見的一種划分方式。高程3中就是這樣來划分js的類型系統的。但是,因為我覺得愛民老師這樣的划分方式也沒什么不妥。一切都是看待問題的角度不同導致的。而愛民老師將null歸類到對象類型里面去,因為在js中除了undefined之外的都是對象。

而“u dot know”直接耳提面命的告訴我:你一直理解的js類型系統,是錯的!

//'u dot kown'里的注解
注 1:原理是這樣的,不同的對象在底層都表示為二進制,在 JavaScript 中二進制前三位都為 0 的話會被判
斷為 object 類型,null 的二進制表示是全 0,自然前三位也是 0,所以執行 typeof 時會返回“object”。

 

3.到底怎么理解?

因為有了疑慮,所以我們要去探查真相!

終於,賀老給了我們一個很好的回答

hax主要說了以下幾個點:

  • 愛民老師是按照自己的理解來分類的,而不是按照ECMA來照本宣科的,況且他寫書的時候ES5/ES6還沒有出來,而ES5之前的ES規范其實都寫得比較爛
  • 現在比較普遍的認知是,typeof null返回“object”是一個歷史錯誤(JS的發明者Brendan Eich自己也是這樣說的),只是因為要保持語言的兼容性而維持至今。從ES5制定開始就有動議將typeof null改為返回“null”(如啟動node加上“--harmony_typeof”參數,即是如此),但是當前ES6標准草案仍然維持了原樣。  
  • 按照愛民的意見,也可在某種程度上理解為null實為object類型的一個特殊值。在諸如Java這樣的語言中,一個變量若是primitive類型,均不可賦以null值,而若是 object,則均可賦以null值。因為在理解上來說,null實際是引用(reference)的特殊值(表示沒有指向任何實際對象)
  • ECMA是如何划分概念,主要是依據ECMA的邏輯,而不是其他標准。所以從ECMA的邏輯看,類型系統是這樣划分的,也是合理的 

 

4.結論

古人常雲:盡信書不如無書。書中的知識也是作者按照自己對語言了解的深度和他自己涉獵的廣度的一個綜合的體現。
而我們看書,其實就是和作者交流的過程。
 
所以,你說愛民老師說的對嗎?
對也不對!狹義的看,如果按照ECMA來說,就不對。但是,廣義的看,如果你覺得按照愛民老師的划分,讓你對js的類型系統保持了你對“對象”一貫的理解,那就是對的。
那你說,ECMA是對的嗎?
對也不對!狹義的看,標准一般都是對的。但是,廣義的看,如果你覺得把null不歸為對象系統,不符合你對高級語言的認知,那也可以說是不對。
 
那么,回到我這篇文章的標題,js中的null,你覺得是對象嗎?
我可能並不會去正面回答我提出的問題了,但是,我想說的是,至少我現在並不會對於"u dot know"里面說到的這個問題而耿耿於懷了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM