String
Baseline 廣泛可用 *
String 物件用於表示和操作字元序列。
描述
字串對於儲存文字形式的資料非常有用。字串最常用的操作包括:檢查其length(長度);使用 + 和 += 字串運算子構建和連線它們;使用 indexOf() 方法檢查子字串是否存在或其位置;或者使用 substring() 方法提取子字串。
建立字串
字串可以透過字串字面量作為原始值建立,也可以使用 String() 建構函式作為物件建立。
const string1 = "A string primitive";
const string2 = 'Also a string primitive';
const string3 = `Yet another string primitive`;
const string4 = new String("A String object");
字串原始值和字串物件在許多行為上是相同的,但也有其他重要的區別和注意事項。請參閱下面的“字串原始值和字串物件”。
字串字面量可以使用單引號或雙引號指定,它們被視為相同,也可以使用反引號字元 `。最後一種形式指定了模板字面量:透過這種形式,你可以插入表示式。有關字串字面量語法的更多資訊,請參閱詞法語法。
字元訪問
有兩種方法可以訪問字串中的單個字元。第一種是 charAt() 方法。
"cat".charAt(1); // gives value "a"
另一種方法是將字串視為類陣列物件,其中單個字元對應於數字索引。
"cat"[1]; // gives value "a"
當使用方括號表示法進行字元訪問時,嘗試刪除或為這些屬性賦值將不會成功。涉及的屬性既不可寫入也不可配置。(有關更多資訊,請參閱 Object.defineProperty()。)
比較字串
使用小於和大於運算子來比較字串。
const a = "a";
const b = "b";
if (a < b) {
// true
console.log(`${a} is less than ${b}`);
} else if (a > b) {
console.log(`${a} is greater than ${b}`);
} else {
console.log(`${a} and ${b} are equal.`);
}
請注意,所有比較運算子,包括 === 和 ==,都對字串進行大小寫敏感的比較。一種常見的進行大小寫不敏感字串比較的方法是,在比較之前將兩者轉換為相同的大小寫(大寫或小寫)。
function areEqualCaseInsensitive(str1, str2) {
return str1.toUpperCase() === str2.toUpperCase();
}
選擇使用 toUpperCase() 還是 toLowerCase() 轉換大多是隨意的,而且當超出拉丁字母表時,兩者都不能完全健壯。例如,德語小寫字母 ß 和 ss 都會被 toUpperCase() 轉換為 SS,而土耳其字母 ı 如果不特別使用 toLocaleLowerCase("tr"),則會被 toLowerCase() 錯誤地報告為與 I 不等。
const areEqualInUpperCase = (str1, str2) =>
str1.toUpperCase() === str2.toUpperCase();
const areEqualInLowerCase = (str1, str2) =>
str1.toLowerCase() === str2.toLowerCase();
areEqualInUpperCase("ß", "ss"); // true; should be false
areEqualInLowerCase("ı", "I"); // false; should be true
一個區域設定感知且健壯的測試大小寫不敏感相等性的解決方案是使用 Intl.Collator API 或字串的 localeCompare() 方法——它們共享相同的介面——並將 sensitivity 選項設定為 "accent" 或 "base"。
const areEqual = (str1, str2, locale = "en-US") =>
str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0;
areEqual("ß", "ss", "de"); // false
areEqual("ı", "I", "tr"); // true
localeCompare() 方法以類似於 strcmp() 的方式啟用字串比較——它允許以區域設定感知的方式對字串進行排序。
字串原始值和字串物件
請注意,JavaScript 區分 String 物件和原始字串值。(Boolean 和 Numbers 也是如此。)
字串字面量(由雙引號或單引號表示)以及在非建構函式上下文(即,不使用 new 關鍵字呼叫)中從 String 呼叫返回的字串都是原始字串。在需要對原始字串呼叫方法或進行屬性查詢的上下文中,JavaScript 會自動包裝原始字串,並在包裝物件上呼叫方法或執行屬性查詢。
const strPrim = "foo"; // A literal is a string primitive
const strPrim2 = String(1); // Coerced into the string primitive "1"
const strPrim3 = String(true); // Coerced into the string primitive "true"
const strObj = new String(strPrim); // String with new returns a string wrapper object.
console.log(typeof strPrim); // "string"
console.log(typeof strPrim2); // "string"
console.log(typeof strPrim3); // "string"
console.log(typeof strObj); // "object"
警告:你很少會發現自己將 String 作為建構函式使用。
字串原始值和 String 物件在使用 eval() 時也會產生不同的結果。傳遞給 eval 的原始值被視為原始碼;String 物件被視為所有其他物件一樣,透過返回物件。例如:
const s1 = "2 + 2"; // creates a string primitive
const s2 = new String("2 + 2"); // creates a String object
console.log(eval(s1)); // returns the number 4
console.log(eval(s2)); // returns the string "2 + 2"
由於這些原因,當代碼遇到 String 物件而預期原始字串時,程式碼可能會中斷,儘管通常作者不必擔心這種區別。
String 物件始終可以使用 valueOf() 方法轉換為其原始對應項。
console.log(eval(s2.valueOf())); // returns the number 4
字串強制轉換
許多期望字串的內建操作會首先將其引數強制轉換為字串(這很大程度上是 String 物件與字串原始值行為相似的原因)。該操作可以總結如下:
- 字串按原樣返回。
undefined轉換為"undefined"。null轉換為"null"。true轉換為"true";false轉換為"false"。- 數字使用與
toString(10)相同的演算法進行轉換。 - BigInts 使用與
toString(10)相同的演算法進行轉換。 - Symbols 會丟擲
TypeError。 - 物件首先透過呼叫其
[Symbol.toPrimitive]()(以"string"為提示)、toString()和valueOf()方法(按此順序)轉換為原始值。然後將生成的原始值轉換為字串。
在 JavaScript 中有幾種方法可以達到幾乎相同的效果。
- 模板字面量:
`${x}`為嵌入的表示式執行上述完全相同的字串強制轉換步驟。 String()函式:String(x)使用相同的演算法轉換x,不同之處在於 Symbols 不會丟擲TypeError,而是返回"Symbol(description)",其中description是 Symbol 的描述。- 使用
+運算子:"" + x將其運算元強制轉換為原始值而不是字串,並且對於某些物件,其行為與正常字串強制轉換完全不同。有關更多詳細資訊,請參閱其參考頁面。
根據你的用例,你可能希望使用 `${x}`(模仿內建行為)或 String(x)(處理 Symbol 值而不丟擲錯誤),但不應使用 "" + x。
UTF-16 字元、Unicode 碼點和字形簇
字串從根本上表示為 UTF-16 碼元序列。在 UTF-16 編碼中,每個碼元正好是 16 位長。這意味著最多有 216,即 65536 個字元可以表示為單個 UTF-16 碼元。這個字元集被稱為基本多語言平面(BMP),包括拉丁字母、希臘字母、西裡爾字母以及許多東亞字元等最常見字元。每個碼元都可以用 \u 後跟四個十六進位制數字在字串中書寫。
然而,整個 Unicode 字元集遠大於 65536。額外的字元在 UTF-16 中以代理對的形式儲存,代理對是由兩個 16 位碼元表示一個字元。為避免歧義,代理對的兩個部分必須介於 0xD800 和 0xDFFF 之間,並且這些碼元不用於編碼單個碼元字元。(更精確地說,前導代理,也稱為高代理碼元,其值介於 0xD800 和 0xDBFF(含)之間,而尾隨代理,也稱為低代理碼元,其值介於 0xDC00 和 0xDFFF(含)之間。)每個 Unicode 字元,由一個或兩個 UTF-16 碼元組成,也稱為Unicode 碼點。每個 Unicode 碼點可以用 \u{xxxxxx} 在字串中書寫,其中 xxxxxx 表示 1-6 個十六進位制數字。
“孤立代理”是滿足以下描述之一的 16 位碼元:
- 它在
0xD800–0xDBFF範圍內(即,是前導代理),但它是字串中的最後一個碼元,或者下一個碼元不是尾隨代理。 - 它在
0xDC00–0xDFFF範圍內(即,是尾隨代理),但它是字串中的第一個碼元,或者前一個碼元不是前導代理。
孤立代理不表示任何 Unicode 字元。儘管大多數 JavaScript 內建方法都能正確處理它們,因為它們都是基於 UTF-16 碼元工作的,但孤立代理在與其他系統互動時通常不是有效值——例如,encodeURI() 會對孤立代理丟擲 URIError,因為 URI 編碼使用 UTF-8 編碼,而 UTF-8 沒有孤立代理的編碼。不包含任何孤立代理的字串稱為格式良好的字串,可以安全地與不處理 UTF-16 的函式(例如 encodeURI() 或 TextEncoder)一起使用。你可以使用 isWellFormed() 方法檢查字串是否格式良好,或使用 toWellFormed() 方法清理孤立代理。
除了 Unicode 字元之外,還有一些 Unicode 字元序列應被視為一個視覺單元,稱為字形簇。最常見的情況是表情符號:許多具有多種變體的表情符號實際上是由多個表情符號組成的,通常透過 <ZWJ> (U+200D) 字元連線。
你必須注意你正在迭代的字元級別。例如,split("") 將按 UTF-16 碼元分割,並將代理對分開。字串索引也指的是每個 UTF-16 碼元的索引。另一方面,[Symbol.iterator]() 按 Unicode 碼點迭代。迭代字形簇將需要一些自定義程式碼。
"😄".split(""); // ['\ud83d', '\ude04']; splits into two lone surrogates
// "Backhand Index Pointing Right: Dark Skin Tone"
[..."👉🏿"]; // ['👉', '🏿']
// splits into the basic "Backhand Index Pointing Right" emoji and
// the "Dark skin tone" emoji
// "Family: Man, Boy"
[..."👨👦"]; // [ '👨', '', '👦' ]
// splits into the "Man" and "Boy" emoji, joined by a ZWJ
// The United Nations flag
[..."🇺🇳"]; // [ '🇺', '🇳' ]
// splits into two "region indicator" letters "U" and "N".
// All flag emojis are formed by joining two region indicator letters
建構函式
String()-
建立
String物件。當作為函式呼叫時,它返回型別為 String 的原始值。
靜態方法
String.fromCharCode()-
返回使用指定的 Unicode 值序列建立的字串。
String.fromCodePoint()-
返回使用指定的碼點序列建立的字串。
String.raw()-
返回從原始模板字串建立的字串。
例項屬性
這些屬性在 String.prototype 上定義,並由所有 String 例項共享。
String.prototype.constructor-
建立例項物件的建構函式。對於
String例項,初始值是String建構函式。
這些屬性是每個 String 例項的自有屬性。
length-
反映字串的
length(長度)。只讀。
例項方法
String.prototype.at()-
返回指定
index處的字元(正好一個 UTF-16 碼元)。接受負整數,負整數表示從字串末尾開始倒數。 String.prototype.charAt()-
返回指定
index處的字元(正好一個 UTF-16 碼元)。 String.prototype.charCodeAt()-
返回指定
index處的 UTF-16 碼元值的數字。 String.prototype.codePointAt()-
返回一個非負整數 Number,它是從指定
pos開始的 UTF-16 編碼碼點的碼點值。 String.prototype.concat()-
合併兩個(或更多)字串的文字並返回一個新字串。
String.prototype.endsWith()-
判斷一個字串是否以字串
searchString的字元結尾。 String.prototype.includes()-
判斷呼叫字串是否包含
searchString。 String.prototype.indexOf()-
返回此字串中
searchValue第一次出現的索引,如果未找到則返回-1。 String.prototype.isWellFormed()-
返回一個布林值,指示此字串是否包含任何孤立代理。
String.prototype.lastIndexOf()-
返回此字串中
searchValue最後一次出現的索引,如果未找到則返回-1。 String.prototype.localeCompare()-
返回一個數字,指示參考字串
compareString在排序順序中是位於給定字串之前、之後還是與之等效。 String.prototype.match()-
用於將正則表示式
regexp與字串進行匹配。 String.prototype.matchAll()-
返回所有
regexp匹配項的迭代器。 String.prototype.normalize()-
返回呼叫字串值的 Unicode 標準化形式。
String.prototype.padEnd()-
用給定字串從末尾填充當前字串,並返回一個長度為
targetLength的新字串。 String.prototype.padStart()-
用給定字串從開頭填充當前字串,並返回一個長度為
targetLength的新字串。 String.prototype.repeat()-
返回一個由物件元素重複
count次組成的字串。 String.prototype.replace()-
用於使用
replaceWith替換searchFor的出現。searchFor可以是字串或正則表示式,replaceWith可以是字串或函式。 String.prototype.replaceAll()-
用於使用
replaceWith替換所有searchFor的出現。searchFor可以是字串或正則表示式,replaceWith可以是字串或函式。 String.prototype.search()-
在正則表示式
regexp和呼叫字串之間搜尋匹配。 String.prototype.slice()-
提取字串的一部分並返回一個新字串。
String.prototype.split()-
返回一個字串陣列,該陣列是透過在子字串
sep出現的位置拆分呼叫字串而填充的。 String.prototype.startsWith()-
判斷呼叫字串是否以字串
searchString的字元開頭。 String.prototype.substr()已棄用-
返回字串的一部分,從指定索引開始,並在此後延伸給定數量的字元。
String.prototype.substring()-
返回一個新字串,其中包含呼叫字串中從(或介於)指定索引(或索引之間)的字元。
String.prototype.toLocaleLowerCase()-
字串中的字元被轉換為小寫,同時遵守當前區域設定。
對於大多數語言,這將返回與
toLowerCase()相同的結果。 String.prototype.toLocaleUpperCase()-
字串中的字元被轉換為大寫,同時遵守當前區域設定。
對於大多數語言,這將返回與
toUpperCase()相同的結果。 String.prototype.toLowerCase()-
返回轉換為小寫的呼叫字串值。
String.prototype.toString()-
返回表示指定物件的字串。覆蓋
Object.prototype.toString()方法。 String.prototype.toUpperCase()-
返回轉換為大寫的呼叫字串值。
String.prototype.toWellFormed()-
返回一個字串,其中此字串的所有孤立代理都替換為 Unicode 替換字元 U+FFFD。
String.prototype.trim()-
從字串的開頭和結尾修剪空格。
String.prototype.trimEnd()-
從字串的末尾修剪空格。
String.prototype.trimStart()-
從字串的開頭修剪空格。
String.prototype.valueOf()-
返回指定物件的原始值。覆蓋
Object.prototype.valueOf()方法。 String.prototype[Symbol.iterator]()-
返回一個新的迭代器物件,該物件遍歷字串值的碼點,將每個碼點作為字串值返回。
HTML 包裝器方法
警告:已棄用。避免使用這些方法。
它們的用途有限,因為它們基於一個非常舊的 HTML 標準,並且只提供了當前可用 HTML 標籤和屬性的子集。其中許多今天建立的是已棄用或非標準的標記。此外,它們在沒有任何驗證或清理的情況下進行字串連線,這使得它們在直接使用 innerHTML 插入時可能構成安全威脅。請改用 DOM API,例如 document.createElement()。
String.prototype.anchor()已棄用-
<a name="name">(超文字目標) String.prototype.big()已棄用<big>String.prototype.blink()已棄用-
<blink> String.prototype.bold()已棄用<b>String.prototype.fixed()已棄用<tt>String.prototype.fontcolor()已棄用String.prototype.fontsize()已棄用String.prototype.italics()已棄用<i>String.prototype.link()已棄用-
<a href="url">(連結到 URL) String.prototype.small()已棄用<small>String.prototype.strike()已棄用<strike>String.prototype.sub()已棄用<sub>String.prototype.sup()已棄用<sup>
請注意,這些方法不檢查字串本身是否包含 HTML 標籤,因此可能會建立無效 HTML。
"</b>".bold(); // <b></b></b>
它們唯一的轉義是將屬性值中的 "(對於 anchor()、fontcolor()、fontsize() 和 link())替換為 "。
"foo".anchor('"Hello"'); // <a name=""Hello"">foo</a>
示例
字串轉換
String() 函式比呼叫值的 toString() 方法更能可靠地將值轉換為字串,因為前者在用於 null 和 undefined 時也能工作。例如:
// You cannot access properties on null or undefined
const nullVar = null;
nullVar.toString(); // TypeError: Cannot read properties of null
String(nullVar); // "null"
const undefinedVar = undefined;
undefinedVar.toString(); // TypeError: Cannot read properties of undefined
String(undefinedVar); // "undefined"
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-string-objects |
瀏覽器相容性
載入中…