第三章 內建物件
前面兩章曾多次提到過JS的內建物件(natives),像是String 或是 Number 這類。現在我們要深入的瞭解它們了,嘿嘿嘿。
下面列出JS中常見的內建物件
- String()
- Boolean()
- Number()
- Object()
- Function()
- Array()
- Date()
- Error()
- RegExp()
- Symbol() // ES6
如果在瀏覽器中,還有各類的 HTMLDomElement ,ES6裡也有許多新的內建物件。
你看,這些內建物件怎麼像函式呢?其實你可以把它們理解成物件建構函式。
var s = new String('I am a String');
typeof s; //=> 'object'
我們使用之前用過的typeof 檢查一下,並沒有什麼區別,可以認為內建物件是物件的子型別,typeof只能顯式值的型別,因此只能顯示 'object' 'function' 和 'symbol';
[[Class]]屬性
既然 typeof 無能為力,那如何確定其他的內建物件的型別呢。這些內建物件都有一個內建的隱藏屬性[[Class]],需要用 Object.prototype.toString() 使用 call 繫結到該內建物件上來獲取。
Object.prototype.toString.call( [ ] ); //=> "[object Array]"
返回值中的 Array 就是[[Class]]的屬性了,但是這個方法一樣有些奇怪的地方
Object.prototype.toString.call( undefined ); //=> "[object Undefined]"
Object.prototype.toString.call( null ); //=> "[object Null ]"
Object.prototype.toString.call( 1 ); //=> "[object Number]"
Object.prototype.toString.call( 'build-in type' ); //=> "[object String]"
WTF...and more. JS 這個語言中檢測方法怎麼都不按照基本法啊?!內建物件並沒有 null 和 undefined 啊,你們到底湊什麼熱鬧啊,還有 1 和 'buid...' 明明是內建型別,怎麼也成 object 了 ??那是因為內建型別會被裝箱(Boxing Wrappers),那什麼是裝箱呢,裝箱的東西是能吃還是能走私呢?
裝箱(Boxing Wrappers)
前面我們看到在檢查內建型別的時候,它們變成了物件,這種行為就叫裝箱。那裝箱有什麼用呢?我猜你可能使用過這個功能但全然沒注意過這個問題
'abc'.length; // 3
'lower'.toUpperCase(); // 'LOWER'
看到了吧,第二本書就介紹了JS的原型鏈機制,我們要知道JS中的所有內建方法都儲存在某個建構函式的prototype物件中,但是像 'abc' 1 這種內建型別並不是物件,沒有屬性也沒有方法,自然也沒有[[proto]](__proto__),不能依靠原型鏈向上呼叫方法,因此在執行某些方法時,JS會把內建型別裝箱成物件,讓其獲取呼叫原型鏈上的方法的能力。
看到這裡你一定想到了一個好主意,就是如果你須要在一個 for 迴圈中 使用 'abc'.length,那JS不是每次都要進行裝箱,你可以預先構造一個 new String('abc') 物件,這樣是不是可以加速執行程式碼了?有趣的問題,你可千萬不要這麼做,因為這個問題早期的開發者早就想到了,因此他們已經做了優化,而如果你想來個預優化處理很可能適得其反。所以建議你不要使用建構函式建立一個內建型別對應的內建物件,而是讓JS自己去裝箱。
拆箱(Unboxing)
既然能裝箱,必然也有拆箱的方法,那就是呼叫 valueOf( ) 這個函式,可以將一個內建物件的primitive值取出。
valueOf( new String('abc') ); // 'abc'
這是一種顯式的拆箱方法,而隱式的拆箱方法在第四章 強制轉型中介紹。
本章小結
- JS的內建物件有10種,都是由 JS 的建構函式用 new 操作符構造的物件(symbol不用new)
- 內建物件有個[[Class]]隱藏屬性,需要用 Object.prototype.toString.call( native )獲取
- 上一條的方法也可以對內建型別獲取其 [[Class]] 屬性,原因是 JS 會在需要時對內建型別進行裝箱
- 裝箱可以讓內建型別獲取原型鏈函式呼叫,但不要手動構造內建型別的物件,這樣並不會提升效能
- 對內建物件應用 valueOf() 方法可以獲取內建物件的 值,這個過程叫拆箱,另外的拆箱方法是強制轉型,第四章介紹。
相關文章
- c++內建函式物件C++函式物件
- 重要內建函式、常見內建函式(瞭解)、可迭代物件、迭代器物件、for迴圈原理、異常捕獲函式物件
- 2.1.2 Python物件導向之反射以及內建方法Python物件反射
- 物件導向程式設計之super內建函式的用法物件程式設計函式
- ES6新特性:JavaScript中內建的延遲物件PromiseJavaScript物件Promise
- JavaSE第三章 物件導向 抽象類 abstractJava物件抽象
- JavaSE第三章筆記(物件導向1)Java筆記物件
- JavaScript內部物件和Date物件JavaScript物件
- 前端筆記之JavaScript物件導向(二)內建建構函式&相關方法|屬性|運算子&繼承&物件導向前端筆記JavaScript物件函式繼承
- Day 14 匿名函式 內建函式 物件導向程式設計函式物件程式設計
- JavaScript 本地物件、內建物件和宿主物件JavaScript物件
- js內建物件JS物件
- JavaScript內建物件JavaScript物件
- Mysql架構與內部模組-第三章MySql架構
- 內建函式函式
- JavaScript的內建物件JavaScript物件
- Document物件內容集合物件
- JSP內建物件JS物件
- ASP內建物件 (轉)物件
- 內建物件、宿主物件和本地物件是什麼物件
- 建構函式建立物件函式物件
- 小陳學JS js內建物件 Date物件JS物件
- Flutter - 內建動畫 APIFlutter動畫API
- node常用內建apiAPI
- Vue的內建指令Vue
- Python 內建方法Python
- MySQL 內建函式MySql函式
- hive內建函式Hive函式
- php 內建函式PHP函式
- Mysql內建函式MySql函式
- 14、內建函式函式
- perl 內建變數變數
- awk內建函式函式
- Oracle內建事件列表Oracle事件
- Linux內建指令Linux
- js內建函式JS函式
- JSP 內建物件(一)JS物件
- 內建物件--Array(陣列)物件陣列