JavaScript 原始包裝類型匯總

前言:

引出問題: 如下一段簡單的代碼,變量a賦予瞭字符串類型原始值"str",通過控制臺打印輸出變量a,隻有“str"。a並沒有定義slice這個方法,但是後續為什麼變量a可以調用slice方法呢?

let a = "str";
console.log(a);  // "str"
console.log(a.slice(1))  // "tr"

針對以上問題,需要追溯到JavaScript中的原始包裝類型。

一、原始包裝類型

為瞭方便操作原始值,ECMAScript提供瞭3種特殊的引用類型:Boolean、Number 和 String

關於Boolean、Number 和 String涉及的方法和屬性很多,這裡僅介紹三種引用類型的 valueOf() 方法和 toString() 方法。

1、Boolean

創建一個Boolean類型的對象實例時,傳入的參數按轉換為Boolean類型值的規則確實是true還是false

(1)valueOf() :返回一個原始值 true 或者 false

let a = new Boolean(true);
console.log(a.valueOf());  // true

(2)toString() :返回字符串 ‘true' 或者 'false'

let b = new Boolean(false);
console.log(b.toString());  // "false"

2、Number

(1)valueOf() :返回對象的原始數值

let a = new Number(12);
console.log(a.valueOf());  // 12

(2)toString() :返回相應基數(進制數)的數值字符串

let b = new Number(123);
console.log(b.toString());  // "123"

3、String

valueOf() 、toString() 和 toLocalString() 都繼承自 Object,均返回對象的原始字符串值

let a = new String('str');
console.log(a.valueOf());  // str
console.log(a.toString());  // str
console.log(a.toLocaleString());  // str

二、原始包裝類型的特點

1、原始值為什麼可以調用一些方法

let s = "str";
console.log(s.slice(1))  // "tr"

如上代碼,第二行中訪問a時,是以讀模式訪問的,也就是要從內存中讀取變量保存的值。

在以讀模式訪問字符串值得任何時候,後臺都會自動執行以下三步:

(1)根據字符串值創建一個 String 類型的實例
(2)調用實例上的特定方法
(3)銷毀實例

即相當於執行瞭以下三行代碼:

// 創建String實例
let s = new String("str");
// 調用特定方法
s.slice(1)
// 銷毀實例
s = null

這種行為則讓原始值擁有瞭對象的行為。

針對佈爾值和數值,也會在後臺執行相同的步驟。

2、引用類型和原始值包裝類型的區別

引用類型和原始值包裝類型的區別主要在於對象的生命周期

  • (1)通過new實例化引用類型後,得到的實例會在離開作用域時被銷毀
  • (2)自動創建的原始值包裝對象則隻會存在於訪問它的那行代碼執行期間。(所以運行時並不能給原始值添加屬性和方法)

3、原始包裝類型構造函數 和 轉型函數

以Number為例:

  • (1)如果直接調用 Number(),執行的是 Number()轉型函數,強制數值類型轉換
  • (2)如果通過new 調用 Number(),執行的是 Number() 構造函數,創建一個Number的實例
let a = Number(1);
console.log(typeof a);   // number
let b = new Number(1);
console.log(typeof b);   // object

一個簡單的知識點,主要自己之前學習太倉促,這些基礎知識點並沒有學習牢固,此復盤整理一下。

推薦閱讀: