首先咱們來看一段代碼示例編程
var str='hello';
var num=1;
var bl=true;
var arr=[1,2,3];
var obj={x:1};
str.toString();
// "hello"
num.toString();
// "1"
bl.toString();
// "true"
arr.toString();
// "1,2,3"
obj.toString();
// "[object Object]"」
複製代碼
從上面的代碼來看,彷佛str,num,bl,arr,obj這五個變量都是實例對象,由於它們均可以調用對象的實例方法toString
,然而經過typeof
方法對着五個變量進行類型判斷,發現狀況並不是如此。bash
typeof str
// string
typeof num
// number
typeof bl
// boolean
typeof arr
// object
typeof obj
// object
複製代碼
經過上面的代碼,咱們發現,實際上只有arr、obj這兩個變量纔會被識別成object,其他的str、num、bl則分別對應string、number、boolean數據類型,這彷佛和咱們以前的判斷很矛盾,在這裏咱們就須要引出JavaScript中的包裝對象了。app
對象是 JavaScript 語言最主要的數據類型,三種原始類型的值——數值、字符串、布爾值——在必定條件下,也會自動轉爲對象,也就是原始類型的「包裝對象」(wrapper)。ui
所謂「包裝對象」,指的是與數值、字符串、布爾值分別相對應的Number、String、Boolean三個原生對象。這三個原生對象能夠把原始類型的值變成(包裝成)對象。this
var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
v1 === 123 // false
v2 === 'abc' // false
v3 === true // false
複製代碼
包裝對象的設計目的,首先是使得「對象」這種類型能夠覆蓋 JavaScript 全部的值,整門語言有一個通用的數據模型,其次是使得原始類型的值也有辦法調用本身的方法。spa
正是有了包裝對象的存在,咱們才能夠把字符串、數值、布爾值這三個原始類型的值當成實例對象進行使用,調用各自對應的包裝對象的實例方法和實例屬性。prototype
某些場合,原始類型的值會自動看成包裝對象調用,即調用包裝對象的屬性和方法。這時,JavaScript 引擎會自動將原始類型的值轉爲包裝對象實例,並在使用後馬上銷燬實例。設計
好比,字符串能夠調用length屬性,返回字符串的長度。code
'abc'.length
// 3
typeof 'abc'
// string
複製代碼
上面代碼中,abc是一個字符串,自己不是對象,不能調用length屬性。JavaScript 引擎自動將其轉爲包裝對象,在這個對象上調用length屬性。調用結束後,這個臨時對象就會被銷燬。這就叫原始類型與實例對象的自動轉換。對象
var str = 'abc';
str.length // 3
// 等同於
var strObj = new String(str)
// String {
// 0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"
// }
strObj.length // 3
複製代碼
雖然字符串等類型的值能夠臨時轉換成包裝對象,可是這些值並非真正的對象。
var s1 = 'Hello World';
s1.x = 123;
s1.x // undefined
typeof s1
// string
var s2=new String('Hello World');
s2.x=123;
s2.x // 123;
typeof s2;
// object
複製代碼
從上面的例子,咱們能夠看出,被包裝成的實例對象本質上依舊是字符串類型,所以這些值即便被包裝成對象,也只是只讀對象。
除了原生的實例方法,包裝對象還能夠自定義方法和屬性,供原始類型的值直接調用。好比,咱們能夠新增一個double方法,使得字符串和數字翻倍。
String.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
'abc'.double()
// abcabc
Number.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
(123).double() // 246
複製代碼
JavaScript的包裝對象提供給了開發者像操做對象同樣操做string、number、boolean值的能力,體現了JavaScript是一門面向對象編程的開發語言。
同時,開發者也應該牢記被包裝成的實例對象與真正的實例對象的區別,避免一些操做錯誤,這也是JavaScript新手在操做實例對象時,經常會陷入誤區。