String對象
本文參考MDN做的詳細整理,方便大家參考[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
JavaScript中的 String 類型用於表示文本型的數據. 它是由無符號整數值(16bit)作為元素而組成的集合. 字符串中的每個元素在字符串中占據一個位置. 第一個元素的index值是0, 下一個元素的index值是1, 以此類推. 字符串的長度就是字符串中所含的元素個數.
String 對象是對原始string類型的封裝,你可以在String字面值上使用String對象的任何方法—JavaScript自動把String字面值轉換為一個臨時的String對象, 然后調用其相應方法,最后丟棄此臨時對象.在String字面值上也可以使用String.length屬性
訪問字符串的單個字符方法:
- 獲取字符串的某一單個字符有兩種方法。 第一種是使用 charAt 方法:
return 'cat'.charAt(1); // returns "a"
- 另一種方法 (在ECMAScript 5中有所介紹) 是把字符串當作一個類數組對象,其中的每個字符對應一個數值索引:
return 'cat'[1]; // returns "a"
使用括號訪問字符串不可以對其進行刪除或添加,因為對應屬性並不是可讀或可寫的。
- 通常,我們都使用字符串的字面量寫法
- 可以使用 String 函數來將其他值 生成或轉換 成字符串:
String(thing)
new String(thing)
字符串比較:可以用‘>’ 或'<'來對兩個字符、字符串進行比較。
除了普通的可打印字符以外,一些特殊的字符可以通過其轉義形式放入字符串中:
- 16進制轉義序列在\x之后的數值將被認為是一個16進制數:'\xA9' // "©"
- Unicode轉義序列在\u之后需要至少4個字符:'\u00A9' // "©"
- Unicode code point escapes:這是ECMAScript 6中的新特性. 有了Unicode code point escapes, 任何字符都可以用16進制數轉義, 這使得通過Unicode轉義表示大於0x10FFFF的字符成為可能.
- 使用簡單的Unicode轉義時通常需要分別寫字符相應的兩個部分(譯注:大於0x10FFFF的字符需要拆分為相應的兩個小於0x10FFFF的部分)來達到同樣的效果.請參閱 String.fromCodePoint() 或 String.prototype.codePointAt().
'\u{2F804}'
// the same with simple Unicode escapes
'\uD87E\uDC04'
String對象的方法(各個方法詳解見本文底部)
模板字符串:ES6新特性
模板字符串允許嵌入表達式,並且支持多行字符串和字符串插補特性。
語法
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
tag `string text ${expression} string text`
模板字符串使用反引號 (` `) 來代替普通字符串中的用雙引號和單引號。模板字符串可以包含特定語法(${expression})的占位符。占位符中的表達式和周圍的文本會一起傳遞給一個默認函數,該函數負責將所有的部分連接起來,如果一個模板字符串由表達式開頭,則該字符串被稱為帶標簽的模板字符串,該表達式通常是一個函數,它會在模板字符串處理后被調用,在輸出最終結果前,你都可以在通過該函數對模板字符串來進行操作處理。
多行字符串、表達式插補
使用普通字符串,換行需要\n,插入表達式需要分段:
var a = 5;
var b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 * a + b) + ".");
// "Fifteen is 15 and
// not 20."
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
帶標簽的模板字符串
模板字符串的一種更高級的形式稱為帶標簽的模板字符串。它允許您通過標簽函數修改模板字符串的輸出。標簽函數的第一個參數是一個包含了字符串字面值的數組(在本例中分別為“Hello”和“world”);第二個參數,在第一個參數后的每一個參數,都是已經被處理好的替換表達式(在這里分別為“15”和“50”)。 最后,標簽函數返回處理好的字符串。在后面的示例中,標簽函數的名稱可以為任意的合法標示符。
var a = 5;
var b = 10;
function tag(strings, ...values) {
console.log(strings[0]); // "Hello "
console.log(strings[1]); // " world "
console.log(values[0]); // 15
console.log(values[1]); // 50
return "Bazinga!";
}
tag`Hello ${ a + b } world ${ a * b}`;
// "Bazinga!"
原始字符串
在標簽函數的第一個參數中,存在一個特殊的屬性raw ,我們可以通過它來訪問模板字符串的原始字符串。
function tag(strings, ...values) {
console.log(strings.raw[0]);
// "string text line 1 \\n string text line 2"
}
tag`string text line 1 \n string text line 2`;
另外,使用String.raw() 方法創建原始字符串和使用默認模板函數和字符串連接創建是一樣的。
String.raw`Hi\n${2+3}!`;
// "Hi\\n5!"
安全性
由於模板字符串能夠訪問變量和函數,因此不能由不受信任的用戶來構造。
`${console.warn("this is",this)}`; // "this is" Window
let a = 10;
console.warn(`${a+=20}`); // "30"
console.warn(a); // 30
String對象的方法:
靜態方法
String.fromCharCode(num1, ..., numN)
根據指定的 Unicode 編碼中的序號值來返回一個字符串,該方法返回一個字符串,而不是一個 String 對象。
- 盡管絕大部分常用的 Unicode 值可以用一個 16-bit 數字表示,並且對於絕大部分值 fromCharCode() 返回一個字符(即對於絕大部分字符 UCS-2 值是 UTF-16 的子集),但是為了處理所有的 Unicode 值(至 21 bits),只用 fromCharCode() 是不足的。
- 該方法不支持Unicode碼點大於0xFFFF的字符,即傳入的參數不能大於0xFFFF,根本原因在於,碼點大於0xFFFF的字符(高位編碼字符)占用四個字節,而JavaScript只支持兩個字節的字符。必須把碼點大於0xFFFF的字符拆成兩個字符表示。
- 由於高位編碼字符是用兩個低位編碼(lower value)表示形成的一個字符,因此String.fromCodePoint() (ES6 草案的一部分)被用來返回這樣一對低位編碼,從而可以完全表示這些高位編碼字符。
String.fromCodePoint(num1[, ...[, numN]]) ES6
使用指定的unicode參數返回一個primitive的字符串。與fromCharCode功能類似,但是支持的Unicode字符更全,但是瀏覽器支持情況不是太好,目前ie以及safari還不支持。另外,性能並沒有fromCharCode快。因為是ES6當中的新定義的特性,所以目前還不適合放到正式產品環境中去使用。
- 如果傳入無效的Unicode編碼,將會拋出一個RangeError
String.raw(callSite, ...substitutions) ES6
是一個模板字符串的標簽函數,是用來獲取一個模板字符串的原始字面量值的。
- callSite 一個模板字符串的“調用點對象”。
- ...substitutions 任意個可選的參數,表示任意個內插表達式對應的值。
-
如果第一個參數沒有傳入一個格式良好的調用點對象,則會拋出 TypeError 異常。
-
像所有的標簽函數一樣,你通常不需要把它看成一個普通函數,你只需要把它放在模板字符串前面就可以了,而不是在它后面加個括號和一堆參數來調用它,引擎會替你去調用它:
String.raw `Hi\n!`;
// "Hi\\n!",這里得到的不是 Hi 后面跟個換行符,而是跟着 \\ 和 n 兩個字符
String.raw `Hi\u000A!`;
// "Hi\\u000A!",同上,這里得到的會是 \\、u、0、0、0、A 6個字符,
// 任何類型的轉義形式都會失效,保留原樣輸出,不信你試試.length
let name = "Bob";
String.raw `Hi\n${name}!`;
// "Hi\\nBob!",內插表達式還可以正常運行
String.raw({raw: "test"}, 0, 1, 2);
// "t0e1s2t",我認為你通常不需要把它當成普通函數來調用
跟HTML無關的方法
String.prototype.charAt(index)
返回字符的特定位置,index :0~length-1。如果指定的 index 值超出了該范圍,則返回一個空字符串。
String.prototype.charCodeAt(index)
返回表示給定索引的字符的Unicode的值。是String.fromCharCode()方法的反操作
- index 一個大於等於 0,小於字符串長度的整數。如果不是一個數值,則默認為 0。
- 如果指定的 index 小於 0 或不小於字符串的長度,則 charCodeAt 返回 NaN。
- 返回0到65535之間的整數,代表索引處字符的UTF-16編碼單元(在Unicode編碼單元表示一個單一的UTF-16編碼單元的情況下,UTF-16編碼單元匹配Unicode編碼單元。否則,比如Unicode 編碼單元 > 0x10000 的情況下,只能匹配Unicode代理對的第一個編碼單元)。如果你希望得到整點編碼值,使用codePointAt()
- 注意,charCodeAt 總是返回一個小於 65,536 的值。這是因為高位編碼單元(higher code point)使用一對(低位編碼(lower valued))代理偽字符("surrogate" pseudo-characters)來表示,從而構成一個真正的字符。因此,為了查看或復制(reproduce)65536 及以上編碼字符的完整字符,不僅需要獲取 charCodeAt(i) 的值,也需要獲取 charCodeAt(i+1) 的值
String.prototype.concat(string2, string3[, ..., stringN])
將一個或多個字符串與原字符串連接合並,形成一個新的字符串並返回。concat 方法並不影響原字符串。
- 為了提高性能,強烈建議使用 賦值操作符(+, +=)代替 concat 方法
String.prototype.indexOf(searchValue[, fromIndex])
從字符串對象中返回首個被發現的給定值的索引值,如果沒有找到則返回-1。indexOf 方法區分大小寫
- fromIndex 可選 表示調用該方法的字符串中開始查找的位置。可以是任意整數。默認值為 0。如果 fromIndex < 0 則查找整個字符串(如同傳進了 0)。如果 fromIndex >= str.length,則該方法返回 -1,除非被查找的字符串是一個空字符串,此時返回 str.length。
String.prototype.lastIndexOf(searchValue[, fromIndex])
從字符串對象中返回最后一個被發現的給定值的索引值,如果沒有找到則返回-1。
- fromIndex 從調用該方法字符串的此位置處開始查找。可以是任意整數。默認值為 str.length。如果為負值,則被看作 0。如果 fromIndex > str.length,則 fromIndex 被看作 str.length。
String.prototype.localeCompare(compareStr[, locales[, options]]) 新的 locales 、 options 參數要求IE11,Safari不支持
返回一個數字來表明調用該函數的字符串的排列順序是否在某個給定的字符串compareStr的前面或者后面,或者是一樣的(編碼中的位置)。在 compareStr 前面時返回負數,作 compareStr 后面時返回正數,相同位置時返回0
- 新的 locales 、 options 參數能讓應用程序定制函數的行為即指定用來排序的語言。 locales 和 options 參數是依賴於具體實現的,在舊的實現中這兩個參數是完全被忽略的
- 查閱瀏覽器支持部分來確定哪些瀏覽器支持 locales 參數和 options 參數, 在功能檢測中檢查對 locales 、options 參數的支持。locales 和 options 參數還沒有被所有閱覽器所支持。檢查是否被支持, 可以給第二個參數傳遞一個 "i" , 判斷是否有異常 RangeError拋出
- 性能: 當比較大量字符串時, 比如比較大量數組時, 最好創建一個Intl.Collator 對象並使用compare 屬性所提供的函數
- 該方法會考慮自然語言的排序情況,如將B排在a的前面,而JavaScript采用的是Unicode碼點比較'B'<'a'
String.prototype.match(regexp)
使用正則表達式與字符串相比較,返回一個包含匹配結果的數組,如果沒有匹配項,則返回 null。當字符串匹配到正則表達式時,match() 方法會提取匹配項。
- 參數regexp 是一個正則表達式對象。如果傳入一個非正則表達式對象,則會隱式地使用 new RegExp(obj) 將其轉換為正則表達式對象
- 如果正則表達式沒有 g 標志,返回和 RegExp.exec(str) 相同的結果。而且返回的數組擁有一個額外的 input 屬性,該屬性包含原始字符串。另外,還擁有一個 index 屬性,該屬性表示匹配結果在原字符串中的索引(以0開始)。
String.prototype.replace(regexp|substr, newSubStr| function)
被用來在正則表達式和字符串直接比較,然后用新的子串來替換被匹配的子串。該方法並不改變調用它的字符串本身,而只是返回一個新的替換后的字符串。
- regexp (pattern)一個 RegExp 對象。該正則所匹配的內容會被第二個參數的返回值替換掉。
- substr (pattern)一個要被 newSubStr 替換的字符串。
- newSubStr (replacement)用於替換掉第一個參數在原字符串中的匹配部分的 String。該字符串中可以內插一些特殊的變量名。參考下面的使用字符串作為參數。
- function (replacement)一個用來創建新子字符串的函數,該函數的返回值將替換掉第一個參數匹配到的結果。參考下面的指定一個函數作為參數。
使用字符串作為參數: 替換字符串newSubStr可以插入下面的特殊變量名:
下面的例子交換一個字符串中兩個單詞的位置,這個腳本使用$1 和 $2 代替替換文本
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);
你可以指定一個函數作為第二個參數。在這種情況下,當匹配執行后, 該函數就會執行。 函數的返回值作為替換字符串。 (注意: 上面提到的特殊替換參數在這里不能被使用。) 另外要注意的是, 如果第一個參數是正則表達式, 並且其為全局匹配模式, 那么這個方法將被多次調用, 每次匹配都會被調用。
下面是該函數的參數:
(精確的參數個數依賴於replace()的第一個參數是否是一個正則表達式對象, 以及這個正則表達式中指定了多少個括號子串。)下面的例子使 newString 變成'abc - 12345 - #$*%':
function replacer(match, p1, p2, p3, offset, string) {
// p1 is nondigits, p2 digits, and p3 non-alphanumerics
return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
String.prototype.search(regexp)
對正則表達式和指定字符串進行匹配搜索,返回第一個出現的匹配項的下標。如果匹配成功,則 search() 返回正則表達式在字符串中首次匹配項的索引。否則,返回 -1。如果參數是字符串,和indexOf方法一樣
- regexp 查找的字符串或者正則表達式對象。如果傳入一個非正則表達式對象,則會使用 new RegExp(obj) 隱式地將其轉換為正則表達式對象。
String.prototype.slice(beginSlice[, endSlice])
摘取一個字符串區域(從beginSlice到endSlice,不含endSlice),,返回一個新的字符串。
- beginSlice從該索引(以 0 為基數)處開始提取原字符串中的字符。如果值為負數,會被當做 sourceLength + beginSlice 看待,這里的sourceLength 是字符串的長度 (例如, 如果beginSlice 是 -3 則看作是: sourceLength - 3)
- endSlice可選。在該索引(以 0 為基數)處結束提取字符串。如果省略該參數,slice會一直提取到字符串末尾。如果該參數為負數,則被看作是 sourceLength + endSlice,這里的 sourceLength 就是字符串的長度(例如,如果 endSlice 是 -3,則是, sourceLength - 3)。
String.prototype.split([separator][, limit])
通過separator將字符串分離成子串,返回由子串組成的數組。
- separator指定用來分割字符串的字符(串)。separator 可以是一個字符串或正則表達式。 當找到一個 seperator時,separator 會從字符串中被移除,返回存進一個數組當中的子字符串。如果忽略 separator 參數,則返回的數組只包含一個元素,該元素是原字符串。如果 separator 是一個空字符串,則 str 將被轉換為由字符串中字符組成的一個數組。
- 如果 separator 是一個正則表達式,且包含捕獲括號(capturing parentheses),則每次匹配到 separator 時,捕獲括號匹配的結果將會插入到返回的數組中。然而,不是所有瀏覽器都支持該特性
- limit一個整數,限定返回的分割片段數量。split 方法仍然分割每一個匹配的 separator,但是返回的數組只會截取最多 limit 個元素。
- 當字符串為空時,split 返回一個包含一個空字符串的數組,而不是一個空數組。
String.prototype.substr(start[, length])
返回字符串中從指定位置開始的指定長度的子字符串.
- start開始提取字符的位置。如果為負值,則被看作 strLength + start,其中 strLength 為字符串的長度(例如,如果 start 為 -3,則被看作 strLength-3)。注意負的 start 參數不被 Microsoft JScript 所支持,需要Polyfill支持
- length可選。提取的字符數。
- 如果 start 為正值,且大於或等於字符串的長度,則 substr 返回一個空字符串
- 如果 length 為 0 或負值,則 substr 返回一個空字符串。如果忽略 length,則 substr 提取字符,直到字符串末尾。
String.prototype.substring(indexStart[, indexEnd])
返回字符串兩個索引之間(或到字符串末尾)的子串。
substring 提取從 indexStart 到 indexEnd(不包括)之間的字符。特別地:
- 如果 indexStart 等於 indexEnd,substring 返回一個空字符串。
- 如果省略 indexEnd,substring 提取字符一直到字符串末尾。
- 如果任一參數小於 0 或為 NaN,則被當作 0。
- 如果任一參數大於 stringName.length,則被當作 stringName.length。
- 如果 indexStart 大於 indexEnd,則 substring 的執行效果就像兩個參數調換了一樣。例如,str.substring(1, 0) == str.substring(0, 1),
- 因此不建議使用這個方法,優先使用slice
String.prototype.toLocaleLowerCase()
根據當前區域設置,將符串中的字符轉換成小寫。對於大多數語言來說,toLowerCase的返回值是一致的。
String.prototype.toLocaleUpperCase()
根據當前區域設置,將字符串中的字符轉換成大寫,對於大多數語言來說,toUpperCase的返回值是一致的。
String.prototype.toLowerCase()
將字符串轉換成小寫並返回。
返回用字符串表示的特定對象。重寫 Object.prototype.toString 方法。
String.prototype.toUpperCase()
將字符串轉換成大寫並返回。
返回一個刪除了字符串兩端的空白字符的新字符串,包括所有的空格字符 (space, tab, no-break space 等)以及所有的行結束符(如 LF,CR)。
兼容寫法:
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
返回特定對象的原始值。重寫 Object.prototype.valueOf 方法。
HTML wrapper methods
下面的方法被限制使用,因為只對可用的HTML表情和屬性提供部分支持。
String.prototype.startsWith(searchString [, position]) ES6 IE無 有Polyfill
判斷字符串的起始位置是否匹配其他字符串中的字符。
- searchString要搜索的子字符串。
- position在 str 中搜索 searchString 的開始位置,默認值為 0,也就是真正的字符串開頭處。
String.prototype.endsWith(searchString [, position]) ES6
判斷當前字符串是否是以另外一個給定的子字符串“結尾”的。可選的position 在 str 中搜索 子串searchString 的結束位置,默認值為 str.length,也就是真正的字符串結尾處。
String.prototype.codePointAt() ES6
返回使用UTF-16編碼的給定位置的值的非負整數。
String.prototype.includes(searchString[, position]) ES6
判斷一個字符串是否包含另一個子字符串,如果是返回true,否則返回false。position 可選,從當前字符串的哪個索引位置開始搜尋子字符串;默認為0。includes() 是區分大小寫的。Polyfill:
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
String.prototype.normalize() ES6
返回調用字符串值的Unicode標准化形式。
String.prototype.repeat(count) ES6 有Polyfill
構造並返回一個重復當前字符串若干次數的新字符串對象。count 介於0和正無窮大之間的整數 : [0, +∞) 。表示在新構造的字符串中重復了多少遍原字符串。
- RangeError: 重復次數不能為負數。
- RangeError: 重復次數必須小於 infinity,且長度不會大於最長的字符串。
下面的方法被限制使用,因為只對可用的HTML表情和屬性提供部分支持:
創建一個 <a> HTML 錨元素,被用作超文本靶標,name表示被創建的標簽的 name 屬性。
- 使用 anchor 方法能夠以編程方式在一個文檔中創建和展現一個錨鏈接。
<a name="name"> text</a>
- 語法上來講,字符串表示你想讓用戶看到的文本。name 字符串參數表示 <a> 元素的 name 屬性。
- 使用 anchor 方法創建的錨點(anchors)將會成為 document.anchors 數組的元素
創建 HTML 元素 “b”,並將字符串加粗展示。將一個字符串嵌入到<b></b>標記中
使用 link 方法創建一個超鏈接 HTML 片段。返回的字符串可以通過 document.write 或 element.innerHTML 方法添加到文檔中。
- url任何能夠指定 a 標簽的 href 屬性的字符串;它應當是有效的 URL(相對或絕對),任何 & 字符將會被轉義為 &,任何 " 字符將會被轉義為 "。
- 使用 link 方法創建的鏈接將會成為 document.links 數組中的元素。查看 document.links。
