常用的原生函數有:
- String()
- Number()
- Boolean()
- Array()
- Object()
- Function()
- RegExp()
- Date()
- Error()
- Symbol()
1.內部屬性
所有typeof
返回值為"object"的對象都包含一個內部屬性[[Class]],這個屬性無法直接訪問,一般通過Object.prototype.toString(..)
來查看。
Object.prototype.toString.call(null);//"[object Null]"
Object.prototype.toString.call(undefined);//"[object Undefined]"
雖然Null()和Undefined()這樣的原生構造函數並不存在,但是內部[[Class]]屬性值仍然是"Null "和"Undefined "。
Object.prototype.toString.call("abc");//"[object String]"
Object.prototype.toString.call(42);//"[object Number]"
Object.prototype.toString.call(true);//"[object Boolean]"
基本類型值被各自的封裝對象自動包裝。
2.封裝對象包裝
由於基本類型值沒有.length
和.toString()
這樣的屬性和方法,需要通過封裝對象才能訪問,此時JavaScript會自動為基本類型值包裝一個封裝對象。
var a = "abc";
a.length;//3
a.toUpperCase();//"ABC"
一般情況下,我們不需要直接使用封裝對象,最好的辦法是讓JavaScript引擎自己決定什么時候使用封裝對象。
如果想要自行封裝基本類型值,可以使用Object(..)
函數。
var a = "abc";
var b = new String(a);
var c = Object(a);
typeof a;//"string"
typeof b;//"object"
typeof c;//"object"
b instanceof String;//true
c instanceof String;//true
Object.prototype.toString.call(b);//"[object String]"
Object.prototype.toString.call(c);//"[object String]"
3.拆封
如果想要得到封裝對象中的基本類型值,可以使用valueOf()
函數:
var a = new String("abc");
var b = new Number(42);
var c = new Boolean(true);
a.valueOf();//"abc"
b.valueOf();//42
c.valueOf();//true
在需要用到封裝對象中的基本類型值的地方會發生隱式拆封。
var a = new String("abc");
var b = a + "";//b的值為"abc"
typeof a;//"object"
typeof b;//"string"
4.原生函數作為構造函數
4.1 Array()
var a = new Array(1,2,3);
console.log(a);//[1,2,3]
var b = [1,2,3];
console.log(b);//[1,2,3]
Array構造函數只帶一個數字參數的時候,該參數會被作為數組的預設長度,而非只充當數組中的一個元素。
var a = new Array(3);
console.log(a.length);//3
console.log(a);//[]
4.2 Object()、Function()和RegExp()
除非萬不得已,否則盡量不要使用Object(..)
/Function(..)
/RegExp(..)
。
4.3 Date()和Error()
創建日期對象必須使用new Date()
。Date(..)
可以帶參數,用來指定日期和時間,而不帶參數的話則使用當前的日期和時間。
Date(..)
主要用來獲得當前的Unix時間戳,該值可以通過日期對象中的getTime()
來獲得。
從ES5開始引入了一個更簡單的方法,即靜態函數Data.now()
。
構造函數Error(..)帶不帶new關鍵字都可。
創建錯誤對象主要是為了獲得當前運行棧的上下文。棧上下文信息包括函數調用棧信息和產生錯誤的代碼行號,以便於調試。
針對特定錯誤類型的原生構造函數很少被直接使用,它們在程序發生異常時會被自動調用。
4.4 Symbol()
ES6新加入了一個基本數據類型——符號。符號是具有唯一性的特殊值 ,用它來命名對象屬性不容易導致重名。
我們可以使用Symbol(..)
原生構造函數來自定義符號。但它比較特殊,不能帶new關鍵字,否則會報錯。
var mysym = Symbol("my own symbol");
console.log(mysym);//Symbol(my own symbol)
console.log(mysym.toString());//"Symbol(my own symbol)"
console.log(typeof mysym);//"symbol"
4.5 原生原型
原生構造函數有自己的.prototype
對象,這些對象包含其對應子類型所特有的行為特征。
例如,將字符串值封裝為字符串對象之后,就能訪問String.prototype
中定義的方法。
所有的函數都可以調用Function.prototype
中的apply(..)
、call(..)
和bind(..)
。
參考:《你不知道的JavaScript》(中卷)
相關閱讀: