Javascript 原始類型的方法

2023-02-17 10:44 更新

JavaScript 允許我們像使用對(duì)象一樣使用原始類型(字符串,數(shù)字等)。JavaScript 還提供了這樣的調(diào)用方法。我們很快就會(huì)學(xué)習(xí)它們,但是首先我們將了解它的工作原理,畢竟原始類型不是對(duì)象(在這里我們會(huì)分析地更加清楚)。

我們來(lái)看看原始類型和對(duì)象之間的關(guān)鍵區(qū)別。

一個(gè)原始值:

  • 是原始類型中的一種值。
  • 在 JavaScript 中有 7 種原始類型:?string?,?number?,?bigint?,?boolean?,?symbol?,?null ?和 ?undefined?。

一個(gè)對(duì)象:

  • 能夠存儲(chǔ)多個(gè)值作為屬性。
  • 可以使用大括號(hào) ?{}? 創(chuàng)建對(duì)象,例如:?{name: "John", age: 30}?。JavaScript 中還有其他種類的對(duì)象,例如函數(shù)就是對(duì)象。

關(guān)于對(duì)象的最好的事兒之一是,我們可以把一個(gè)函數(shù)作為對(duì)象的屬性存儲(chǔ)到對(duì)象中。

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

john.sayHi(); // Hi buddy!

所以我們?cè)谶@里創(chuàng)建了一個(gè)包含 sayHi 方法的對(duì)象 john。

許多內(nèi)建對(duì)象已經(jīng)存在,例如那些處理日期、錯(cuò)誤、HTML 元素等的內(nèi)建對(duì)象。它們具有不同的屬性和方法。

但是,這些特性(feature)都是有成本的!

對(duì)象比原始類型“更重”。它們需要額外的資源來(lái)支持運(yùn)作。

當(dāng)作對(duì)象的原始類型

以下是 JavaScript 創(chuàng)建者面臨的悖論:

  • 人們可能想對(duì)諸如字符串或數(shù)字之類的原始類型執(zhí)行很多操作。最好使用方法來(lái)訪問(wèn)它們。
  • 原始類型必須盡可能的簡(jiǎn)單輕量。

而解決方案看起來(lái)多少有點(diǎn)尷尬,如下:

  1. 原始類型仍然是原始的。與預(yù)期相同,提供單個(gè)值
  2. JavaScript 允許訪問(wèn)字符串,數(shù)字,布爾值和 symbol 的方法和屬性。
  3. 為了使它們起作用,創(chuàng)建了提供額外功能的特殊“對(duì)象包裝器”,使用后即被銷毀。

“對(duì)象包裝器”對(duì)于每種原始類型都是不同的,它們被稱為 String、Number、Boolean、Symbol 和 BigInt。因此,它們提供了不同的方法。

例如,字符串方法 str.toUpperCase() 返回一個(gè)大寫(xiě)化處理的字符串。

用法演示如下:

let str = "Hello";

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

很簡(jiǎn)單,對(duì)吧?以下是 str.toUpperCase() 中實(shí)際發(fā)生的情況:

  1. 字符串 ?str ?是一個(gè)原始值。因此,在訪問(wèn)其屬性時(shí),會(huì)創(chuàng)建一個(gè)包含字符串字面值的特殊對(duì)象,并且具有可用的方法,例如 ?toUpperCase()?。
  2. 該方法運(yùn)行并返回一個(gè)新的字符串(由 ?alert ?顯示)。
  3. 特殊對(duì)象被銷毀,只留下原始值 ?str?。

所以原始類型可以提供方法,但它們依然是輕量級(jí)的。

JavaScript 引擎高度優(yōu)化了這個(gè)過(guò)程。它甚至可能跳過(guò)創(chuàng)建額外的對(duì)象。但是它仍然必須遵守規(guī)范,并且表現(xiàn)得好像它創(chuàng)建了一樣。

數(shù)字有其自己的方法,例如,toFixed(n) 將數(shù)字舍入到給定的精度:

let n = 1.23456;

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

我們將在后面 數(shù)字類型 和 字符串 章節(jié)中看到更多具體的方法。

構(gòu)造器 ?String/Number/Boolean? 僅供內(nèi)部使用

像 Java 這樣的一些語(yǔ)言允許我們使用 new Number(1) 或 new Boolean(false) 等語(yǔ)法,明確地為原始類型創(chuàng)建“對(duì)象包裝器”。

在 JavaScript 中,由于歷史原因,這也是可以的,但極其 不推薦。因?yàn)檫@樣會(huì)出問(wèn)題。

例如:

alert( typeof 0 ); // "number"

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

對(duì)象在 if 中始終為真,所以此處的 alert 將顯示:

let zero = new Number(0);

if (zero) { // zero 為 true,因?yàn)樗且粋€(gè)對(duì)象
  alert( "zero is truthy?!?" );
}

另一方面,調(diào)用不帶 new(關(guān)鍵字)的 String/Number/Boolean 函數(shù)是可以的且有效的。它們將一個(gè)值轉(zhuǎn)換為相應(yīng)的類型:轉(zhuǎn)成字符串、數(shù)字或布爾值(原始類型)。

例如,下面完全是有效的:

let num = Number("123"); // 將字符串轉(zhuǎn)成數(shù)字

null/undefined 沒(méi)有任何方法

特殊的原始類型 null 和 undefined 是例外。它們沒(méi)有對(duì)應(yīng)的“對(duì)象包裝器”,也沒(méi)有提供任何方法。從某種意義上說(shuō),它們是“最原始的”。

嘗試訪問(wèn)這種值的屬性會(huì)導(dǎo)致錯(cuò)誤:

alert(null.test); // error

總結(jié)

  • 除 ?null ?和 ?undefined ?以外的原始類型都提供了許多有用的方法。我們后面的章節(jié)中學(xué)習(xí)這些內(nèi)容。
  • 從形式上講,這些方法通過(guò)臨時(shí)對(duì)象工作,但 JavaScript 引擎可以很好地調(diào)整,以在內(nèi)部對(duì)其進(jìn)行優(yōu)化,因此調(diào)用它們并不需要太高的成本。

任務(wù)


我能為字符串添加一個(gè)屬性嗎?

重要程度: 5

思考下面的代碼:

let str = "Hello";

str.test = 5;

alert(str.test);

你怎么想的呢,它會(huì)工作嗎?會(huì)得到什么樣的結(jié)果?


解決方案

試試運(yùn)行一下:

let str = "Hello";

str.test = 5; // (*)

alert(str.test);

根據(jù)你是否開(kāi)啟了嚴(yán)格模式 use strict,會(huì)得到如下結(jié)果:

  1. ?undefined?(非嚴(yán)格模式)
  2. 報(bào)錯(cuò)(嚴(yán)格模式)。

為什么?讓我們看看在 (*) 那一行到底發(fā)生了什么:

  1. 當(dāng)訪問(wèn) ?str ?的屬性時(shí),一個(gè)“對(duì)象包裝器”被創(chuàng)建了。
  2. 在嚴(yán)格模式下,向其寫(xiě)入內(nèi)容會(huì)報(bào)錯(cuò)。
  3. 否則,將繼續(xù)執(zhí)行帶有屬性的操作,該對(duì)象將獲得 ?test ?屬性,但是此后,“對(duì)象包裝器”將消失,因此在最后一行,?str ?并沒(méi)有該屬性的蹤跡。

這個(gè)例子清楚地表明,原始類型不是對(duì)象。

它們不能存儲(chǔ)額外的數(shù)據(jù)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)