2022 年 6 月 12 日

基本資料類型的方法

JavaScript 讓我們可以像操作物件一樣操作基本資料類型(字串、數字等)。它們也提供可以呼叫的方法。我們很快就會研究這些方法,但首先我們會了解它的運作方式,因為基本資料類型當然不是物件(我們將在此處讓這一點更清楚)。

讓我們看看基本資料類型和物件之間的主要區別。

基本資料類型

  • 是基本資料類型的一個值。
  • 有 7 種基本類型:字串數字大整數布林值符號nullundefined

一個物件

  • 能夠儲存多個值作為屬性。
  • 可以使用 {} 建立,例如:{name: "John", age: 30}。在 JavaScript 中還有其他類型的物件:例如,函式就是物件。

關於物件最棒的一件事,就是我們可以將函式儲存為其屬性之一。

let john = {
  name: "John",
  sayHi: function() {
    alert("Hi buddy!");
  }
};

john.sayHi(); // Hi buddy!

所以這裡我們建立了一個物件 john,其方法為 sayHi

已經存在許多內建物件,例如用於日期、錯誤、HTML 元素等的物件。它們具有不同的屬性和方法。

但是,這些功能是有代價的!

物件比基本類型「更重」。它們需要額外的資源來支援內部機制。

基本類型作為物件

這是 JavaScript 建立者所面臨的矛盾

  • 人們會想對基本類型執行許多操作,例如字串或數字。使用這些方法來存取它們會很棒。
  • 基本類型必須盡可能快速且輕量。

解決方案看起來有點奇怪,但它就是這樣

  1. 基本類型仍然是基本類型。單一值,正如所願。
  2. 這門語言允許存取字串、數字、布林值和符號的方法和屬性。
  3. 為了讓它運作,會建立一個提供額外功能的特殊「物件包裝器」,然後將其銷毀。

「物件包裝器」對於每種基本類型都不同,稱為:字串數字布林值符號大整數。因此,它們提供不同的方法組。

例如,存在字串方法 str.toUpperCase(),它會傳回大寫的 str

以下是它的運作方式

let str = "Hello";

alert( str.toUpperCase() ); // HELLO

很簡單,對吧?以下是 str.toUpperCase() 中實際發生的情況

  1. 字串 str 是基本類型。因此在存取其屬性的那一刻,會建立一個特殊物件,它知道字串的值,並具有有用的方法,例如 toUpperCase()
  2. 該方法會執行並傳回一個新的字串(由 alert 顯示)。
  3. 特殊物件會被銷毀,只留下基本類型 str

因此,基本類型可以提供方法,但它們仍然保持輕量。

JavaScript 引擎高度優化此程序。它甚至可能完全跳過建立額外物件。但它仍必須遵守規範,並表現得好像建立了一個物件。

數字有自己的方法,例如 toFixed(n) 將數字四捨五入到給定的精度

let n = 1.23456;

alert( n.toFixed(2) ); // 1.23

我們將在章節 數字字串 中看到更具體的方法。

建構函式 String/Number/Boolean 僅供內部使用

像 Java 等一些語言允許我們使用類似 new Number(1)new Boolean(false) 的語法明確建立基本類型的「包裝物件」。

在 JavaScript 中,出於歷史原因也可以這樣做,但強烈不建議。這會在幾個地方造成混亂。

例如

alert( typeof 0 ); // "number"

alert( typeof new Number(0) ); // "object"!

物件在 if 中總是為真,所以這裡會顯示警示

let zero = new Number(0);

if (zero) { // zero is true, because it's an object
  alert( "zero is truthy!?!" );
}

另一方面,在沒有 new 的情況下使用相同的函式 String/Number/Boolean 完全沒問題而且很有用。它們會將值轉換為對應的類型:字串、數字或布林值(基本類型)。

例如,這完全有效

let num = Number("123"); // convert a string to number
null/undefined 沒有方法

特殊的基本類型 nullundefined 是例外。它們沒有對應的「包裝物件」,也不提供任何方法。從某種意義上來說,它們是「最基本的」。

嘗試存取此類值的屬性會產生錯誤

alert(null.test); // error

摘要

  • 除了 nullundefined 之外,基本類型提供了許多有用的方法。我們將在後續章節中研究這些方法。
  • 正式來說,這些方法透過暫時物件運作,但 JavaScript 引擎經過良好調整,可以在內部最佳化,因此呼叫它們並不昂貴。

任務

重要性:5

考慮以下程式碼

let str = "Hello";

str.test = 5;

alert(str.test);

你認為它會運作嗎?會顯示什麼?

嘗試執行它

let str = "Hello";

str.test = 5; // (*)

alert(str.test);

根據你是否使用 use strict,結果可能是

  1. undefined(非嚴格模式)
  2. 錯誤(嚴格模式)。

為什麼?讓我們重播在第 (*) 行發生的事情

  1. 當存取 str 的屬性時,會建立一個「包裝物件」。
  2. 在嚴格模式中,寫入它會產生錯誤。
  3. 否則,運算會使用該屬性繼續進行,物件取得 test 屬性,但之後「包裝物件」會消失,因此在最後一行 str 沒有任何屬性的痕跡。

這個範例清楚顯示出原始型別不是物件。

它們無法儲存額外的資料。

教學課程地圖

留言

留言前請先閱讀…
  • 如果你有建議要改進 - 請 提交 GitHub 問題 或發起拉取請求,而不是留言。
  • 如果你無法理解文章中的某個部分 - 請詳細說明。
  • 要插入幾行程式碼,請使用 <code> 標籤,要插入多行程式碼,請將它們包在 <pre> 標籤中,要插入超過 10 行程式碼,請使用沙盒 (plnkrjsbincodepen…)