包裝對象淺談——對比數組、對象(新手必看)

前言

首先我們來看一段代碼示例

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方法對着五個變量進行類型判斷,發現情況並非如此。

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中的包裝對象了。

包裝對象

對象是 JavaScript語言最主要的數據類型,三種原始類型的值——數值、字符串、布爾值——在一定條件下,也會自動轉爲對象,也就是原始類型的“包裝對象”(wrapper)。

所謂“包裝對象”,指的是與數值、字符串、布爾值分別相對應的Number、String、Boolean三個原生對象。這三個原生對象可以把原始類型的值變成(包裝成)對象。

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所有的值,整門語言有一個通用的數據模型,其次是使得原始類型的值也有辦法調用自己的方法。

正是有了包裝對象的存在,我們纔可以把字符串、數值、布爾值這三個原始類型的值當成實例對象進行使用,調用各自對應的包裝對象的實例方法和實例屬性。

自動換成包裝對象

某些場合,原始類型的值會自動當作包裝對象調用,即調用包裝對象的屬性和方法。這時,JavaScript 引擎會自動將原始類型的值轉爲包裝對象實例,並在使用後立刻銷燬實例。

比如,字符串可以調用length屬性,返回字符串的長度。

‘abc’.length

'abc'.length 
// 3
typeof 'abc'

上面代碼中,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新手在操作實例對象時,常常會陷入誤區。

轉載於:https://juejin.im/post/5cf342b5f265da1bcf5dc48a

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章