1. 程式人生 > >在 JavaScript 中,我們能為原始型別新增一個屬性或方法嗎?

在 JavaScript 中,我們能為原始型別新增一個屬性或方法嗎?

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/18d583c0d4084119a03ba18e1e8b99a6~tplv-k3u1fbpfcp-zoom-1.image) # 原始型別的方法 JavaScript 允許我們像使用物件一樣使用原始型別(字串,數字等)。JavaScript 還提供了這樣的呼叫方法。我們很快就會學習它們,但是首先我們將瞭解它的工作原理,畢竟原始型別不是物件(在這裡我們會分析地更加清楚)。 我們來看看原始型別和物件之間的關鍵區別。 一個原始值: - 是原始型別中的一種值。 - 在 JavaScript 中有 7 種原始型別:`string`,`number`,`bigint`,`boolean`,`symbol`,`null` 和 `undefined`。 一個物件: - 能夠儲存多個值作為屬性。 - 可以使用大括號 `{}` 建立物件,例如:`{name: "John", age: 30}`。JavaScript 中還有其他種類的物件,例如函式就是物件。 關於物件的最好的事兒之一是,我們可以把一個函式作為物件的屬性儲存到物件中。 ```js let john = { name: "John", sayHi: function() { alert("Hi buddy!"); } }; john.sayHi(); // Hi buddy! ``` 所以我們在這裡建立了一個包含 `sayHi` 方法的物件 `john`。 許多內建物件已經存在,例如那些處理日期、錯誤、HTML 元素等的內建物件。它們具有不同的屬性和方法。 但是,這些特性(feature)都是有成本的! 物件比原始型別“更重”。它們需要額外的資源來支援運作。 ## 當作物件的原始型別 以下是 JavaScript 建立者面臨的悖論: - 人們可能想對諸如字串或數字之類的原始型別執行很多操作。最好將它們作為方法來訪問。 - 原始型別必須儘可能的簡單輕量。 而解決方案看起來多少有點尷尬,如下: 1. 原始型別仍然是原始的。與預期相同,提供單個值 2. JavaScript 允許訪問字串,數字,布林值和 symbol 的方法和屬性。 3. 為了使它們起作用,建立了提供額外功能的特殊“物件包裝器”,使用後即被銷燬。 “物件包裝器”對於每種原始型別都是不同的,它們被稱為 `String`、`Number`、`Boolean` 和 `Symbol`。因此,它們提供了不同的方法。 例如,字串方法 [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) 返回一個大寫化處理的字串。 用法演示如下: ```js let str = "Hello"; alert( str.toUpperCase() ); // HELLO ``` 很簡單,對吧?以下是 `str.toUpperCase()` 中實際發生的情況: 1. 字串 `str` 是一個原始值。因此,在訪問其屬性時,會建立一個包含字串字面值的特殊物件,並且具有有用的方法,例如 `toUpperCase()`。 2. 該方法執行並返回一個新的字串(由 `alert` 顯示)。 3. 特殊物件被銷燬,只留下原始值 `str`。 所以原始型別可以提供方法,但它們依然是輕量級的。 JavaScript 引擎高度優化了這個過程。它甚至可能跳過建立額外的物件。但是它仍然必須遵守規範,並且表現得好像它建立了一樣。 數字有其自己的方法,例如,[toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 將數字舍入到給定的精度: ```js let n = 1.23456; alert( n.toFixed(2) ); // 1.23 ``` 我們將在後面 [Number 型別](https://zh.javascript.info/number) 和 [字串](https://zh.javascript.info/string) 章節中看到更多具體的方法。 ### 構造器 String/Number/Boolean 僅供內部使用 像 Java 這樣的一些語言允許我們使用 `new Number(1)` 或 `new Boolean(false)` 等語法,明確地為原始型別建立“物件包裝器”。 在 JavaScript 中,由於歷史原因,這也是可以的,但極其 **不推薦**。因為這樣會出問題。 例如: ```js alert( typeof 0 ); // "number" alert( typeof new Number(0) ); // "object"! ``` 物件在 `if` 中始終為真,因此此處的 alert 將顯示: ```js let zero = new Number(0); if (zero) { // zero 為 true,因為它是一個物件 alert( "zero is truthy?!?" ); } ``` 另一方面,呼叫不帶 `new`(關鍵字)的 `String/Number/Boolean` 函式是完全理智和有用的。它們將一個值轉換為相應的型別:轉成字串、數字或布林值(原始型別)。 例如,下面完全是有效的: ```js let num = Number("123"); // 將字串轉成數字 ``` ### null/undefined 沒有任何方法 特殊的原始型別 `null` 和 `undefined` 是例外。它們沒有對應的“物件包裝器”,也沒有提供任何方法。從某種意義上說,它們是“最原始的”。 嘗試訪問這種值的屬性會導致錯誤: ```js alert(null.test); // error ``` ## 總結 - 除 `null` 和 `undefined` 以外的原始型別都提供了許多有用的方法。我們後面的章節中學習這些內容。 - 從形式上講,這些方法通過臨時物件工作,但 JavaScript 引擎可以很好地調整,以在內部對其進行優化,因此呼叫它們並不需要太高的成本。 ## 作業題 先自己做題目再看答案。 ### 我能為字串新增一個屬性嗎? > 重要程度:⭐️⭐️⭐️⭐️⭐️ 思考下面的程式碼: ```js let str = "Hello"; str.test = 5; alert(str.test); ``` 你怎麼想的呢,它會工作嗎?會得到什麼樣的結果? ## 答案: 在微信公眾號「技術漫談」後臺回覆 **`10501`** 獲取作業答案。 --- > 現代 JavaScript 教程:開源的現代 JavaScript 從入門到進階的優質教程。[React 官方文件推薦,與 MDN 並列的 JavaScript 學習教程](https://zh-hans.reactjs.org/docs/getting-started.html#javascript-resources)。 > > 線上免費閱讀:https://zh.javascript.info --- **微信掃描下方二維碼,關注公眾號「技術漫談」,訂閱更多精彩內容。** ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6d62b21deb3b47f7bd7c610d3c658da2~tplv-k3u1fbpfcp-zoom-1