模板字符串(template string) 是增強(qiáng)版的字符串,用反引號(hào) ( ` ) 標(biāo)識(shí)。它可以當(dāng)作普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量。
// 普通字符串
console.log(`In JavaScript \n is a line-feed.`);
// 多行字符串
console.log(`In JavaScript this is
not legal.`);
// 字符串中嵌入變量
let name = "baby";
console.log(`Hi ${name},`);
如果在模板字符串中需要使用反引號(hào),則前面要用反斜杠轉(zhuǎn)義。
let greeting = `\`Yo\` World~`;
console.log(greeting); // `Yo` World~
如果使用模板字符串表示多行字符串,所有的空格和縮進(jìn)都會(huì)被保留在輸出中。
console.log(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`);
如果不想要這些換行,可以使用 trim 方法消除它。
console.log(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`.trim());
模板字符串嵌入變量,需要將變量名寫在 ${} 之中。
let x = 1;
let y = 2;
console.log(`${x} + ${y} = ${x + y}`); // 1 + 2 = 3
console.log(`${x} + ${y * 2} = ${x + y * 2}`); // 1 + 4 = 5
let obj = {x: 1, y: 2};
console.log(`${obj.x + obj.y}`); // 3
模板字符串中還能調(diào)用函數(shù)。
function fn () {
return "or";
}
console.log(`foo ${fn()} bar`); // foo or bar
如果模板字符串中的變量沒有聲明,將報(bào)錯(cuò)。
let msg = `Hello, ${place}`; // Error
由于模板字符串的大括號(hào)內(nèi)部,就是執(zhí)行 JavaScript 代碼,因此如果大括號(hào)內(nèi)部是一個(gè)字符串,將會(huì)原樣輸出。
console.log(`Hello ${'World'}`); // Hello World
模板字符串的功能,不僅僅是上面這些。它可以緊跟在一個(gè)函數(shù)名后面,該函數(shù)將被調(diào)用來處理這個(gè)模板字符串。這被稱為 “標(biāo)簽?zāi)0濉?功能(tagged template)。
alert`123`;
// 等同于
alert(123);
字符串新增方法
String.fromCharCode()
Es5 提供 String.fromCharCode() 方法,用于從 Unicode 碼點(diǎn)返回對(duì)應(yīng)字符,但是這個(gè)方法不能識(shí)別碼點(diǎn)大于 0xFFFF 的字符。
console.log(String.fromCharCode(96)); // "`"
console.log(String.fromCharCode(0x20BB7)); // ?
上面代碼中,String.fromcharCode() 不能識(shí)別大于 0xFFFF 的碼點(diǎn),所以 0x20BB7 就發(fā)生了溢出,最高位 2 被舍棄了,最后返回碼點(diǎn) U + 0BB7 對(duì)應(yīng)的字符,而不是碼點(diǎn) U + 20BB7 對(duì)應(yīng)的字符。
Es6 提供 String.fromCodePoint() 方法,可以識(shí)別大于 0xFFFF 的字符,彌補(bǔ)了 String.fromCharCode() 方法的補(bǔ)助。在作用上,正好與下面的 codePointAt() 方法相反。
console.log(String.fromCodePoint(0x20BB7)); // "??"
如果 String.fromCodePoint() 對(duì)象有多個(gè)參數(shù),則它會(huì)被合并一個(gè)字符串返回。
console.log(String.fromCodePoint(0x78, 0x1f680, 0x79));
console.log(String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'); // true
注意,fromCodePoint() 方法定義在 String 對(duì)象上,而 codePointAt 方法定義在字符串的實(shí)例對(duì)象上。
String.raw()
Es6 還為原生的 String 對(duì)象,提供了一個(gè) raw() 方法。該方法返回一個(gè)斜杠都被轉(zhuǎn)義(斜杠前面再加上一個(gè)斜杠)的字符串,往往用于模板字符串的處理辦法。
console.log(String.raw`Hi\n${2 + 3}!`); // 實(shí)際返回 "Hi\\n5!",顯示的是轉(zhuǎn)義后的結(jié)果 "Hi\n5!"
如果元字符串的斜杠已經(jīng)轉(zhuǎn)義,那么 String.raw() 會(huì)進(jìn)行再次轉(zhuǎn)義。
console.log(String.raw`Hi\\n`); // Hi\\n
console.log(String.raw`Hi\\n` === "Hi\\\\n"); // true
String.raw() 方法可以作為處理模板字符串的基本辦法,它會(huì)將所有變量替換,而且對(duì)斜杠進(jìn)行轉(zhuǎn)義,方便下一步作為字符串來使用。
實(shí)例方法:codePointAt()
JavaScript內(nèi)部,字符串以 UTF - 16 的格式儲(chǔ)存,每個(gè)字符固定為 2 個(gè)字節(jié)。對(duì)于那些需要 4 個(gè)字節(jié)儲(chǔ)存的字符(Unicode 碼點(diǎn)大于 0xFFFF 的字符),JavaScript 會(huì)認(rèn)為它們是兩個(gè)字符。
{
let s = "??";
console.log(s.length); // 2
console.log(s.charAt(0)); // ?
console.log(s.charAt(1)); // ?
console.log(s.charCodeAt(0)); // 55362
console.log(s.charCodeAt(1)); // 57271
}
上代碼中,漢字 “??”(注意,這個(gè)字不是 “吉祥” 的 "吉")的碼點(diǎn)是 0x20BB7,UTF-16 編碼為 0xD842 0xDFB7(十進(jìn)制為 55362 57271),需要 4 個(gè)字節(jié)儲(chǔ)存。對(duì)于這種 4 個(gè)字節(jié)的字符,JavaScript 不能正確處理,字符串長(zhǎng)度會(huì)誤判為 2,而且 charAt() 方法無法讀取整個(gè)字符,charCodeAt() 方法只能分別返回前兩個(gè)字節(jié)和后兩個(gè)字節(jié)的值。
Es6 提供了 codePointAt() 方法,能夠正確處理 4 個(gè)字節(jié)存儲(chǔ)的字符,返回一個(gè)字符的碼點(diǎn)。
{
let s = "??a";
console.log(s.codePointAt(0)); // 134071
console.log(s.codePointAt(1)); // 57271
console.log(s.codePointAt(2)); // 97
}
codePointAt() 方法的參數(shù),是字符在字符串中的位置(從 0 開始)。上面代碼中,JavaScript 將 "??a" 視為三個(gè)字符,codePointAt 方法在第一字符上,正確地認(rèn)識(shí)了 "??",返回了它的十進(jìn)制碼點(diǎn) 134071(即十六進(jìn)制的 20BB7)。
codePointAt() 方法會(huì)正確返回 32 位的 UTF-16 字符的碼點(diǎn)。對(duì)于那些兩個(gè)字節(jié)儲(chǔ)存的常規(guī)字符,它的返回結(jié)果與 charCodeAt() 方法相同。
codePointAt() 方法返回的是碼點(diǎn)的十進(jìn)制值,如果想要十六進(jìn)制的值,可以使用 toString() 方法轉(zhuǎn)換一下。
{
let s = "??a";
console.log(s.codePointAt(0).toString(16)); // "20bb7"
console.log(s.codePointAt(2).toString(16)); // "61"
}
實(shí)例方法:normalize()
許多歐美語言有語調(diào)音符和重音符號(hào)。為表示,Unicode 提供了兩種方法。
// 1、直接代重音符號(hào)的字符
console.log('\u01D1'); // ǒ
// 2、合成字符
console.log('\u004F\u030C'); // ǒ
console.log('\u01D1' === '\u004F\u030C'); // false。這兩種表示方法,在視覺和語義上都等價(jià),但是 JavaScript 不能識(shí)別
console.log('\u01D1'.length, '\u004F\u030C'.length); // 1 2。JavaScript 將合成字符視為兩個(gè)字符,導(dǎo)致兩種表示方法不相等。
Es6 提供字符串實(shí)例的 normalize() 方法,用來將字符串的不同表示方統(tǒng)一為同樣的形式,這稱為 Unicode 正規(guī)化。
console.log('\u01D1'.normalize() === '\u004F\u030C'.normalize()); // true
實(shí)例方法:includes(),startsWith(),endsWith()
JavaScript 只有 indexOf 方法,可以用來確定一個(gè)字符串是否包含在另一個(gè)字符串中。Es6 又提供了三種新方法。
- includes(): 返回布爾值,表示是否找到了參數(shù)字符串。
- startsWith(): 返回布爾值,表示參數(shù)字符串是否在原字符串的頭部。
- endsWith(): 返回布爾值,表示參數(shù)字符串是否在原字符串的尾部。
{
let s = "Hello World~";
console.log(s.startsWith('Hello')); // true
console.log(s.endsWith('~')); // true
console.log(s.includes('o')); // true
}
這三個(gè)方法都支持第二個(gè)參數(shù),表示開始搜索的位置。
{
let s = "Hello World~";
console.log(s.startsWith('World', 6)); // true
console.log(s.endsWith('Hello', 5)); // true
console.log(s.includes('Hello', 6)); // false
}
上面代碼表示,使用第二個(gè)參數(shù) n 時(shí),endsWith 的行為與其他兩個(gè)方法有所不同。它針對(duì)前 n 個(gè)字符,而其他兩個(gè)方法對(duì)從第 n 個(gè)位置直到字符串結(jié)束。
實(shí)例方法:repeat()
repeat() 方法返回一個(gè)新字符串,表示將原字符串重復(fù) n 次。
console.log('x'.repeat(3)); // "xxx"
console.log('hello'.repeat(2)); // "hellohello"
console.log('na'.repeat(0)); // ""
參數(shù)如果是小數(shù),會(huì)被取整。
console.log('na'.repeat(2.9)); // "nana"
如果 repeat 的參數(shù)是負(fù)數(shù)或者 Infinity,會(huì)報(bào)錯(cuò)。
console.log('na'.repeat(Infinity)); // error
console.log('na'.repeat(-1)); // error
但是,如果參數(shù)是 0 到 -1 之間的小數(shù),則等同于 0,這是因?yàn)闀?huì)先進(jìn)性取整運(yùn)算。0 到 -1 之間的小數(shù),取證后等于 -0,repeat 視為 0。
console.log('no'.repeat(-0.9)); // ""
參數(shù) NaN 等同于 0。
console.log('na'.repeat(NaN)); // ""
如果 repeat() 的參數(shù)是字符串,則會(huì)先轉(zhuǎn)換為數(shù)字。如果 repeat() 的參數(shù)是字符串,則會(huì)先轉(zhuǎn)換為數(shù)字。
console.log('na'.repeat('na')); // ""。 "na" ==> Number('na') ==> NaN == 0
console.log('na'.repeat('3')); // "nanana"
實(shí)例方法:padStart(),padEnd()
Es2017 引入字符串補(bǔ)全長(zhǎng)度的功能。如果某個(gè)字符串不夠指定長(zhǎng)度,會(huì)在頭部或尾部補(bǔ)全。padStart() 用于頭部補(bǔ)全,padEnd() 用于尾部補(bǔ)全。
padStart() 和 padEnd() 一共接收兩個(gè)參數(shù),第一個(gè)參數(shù)是字符串補(bǔ)全生效的最大長(zhǎng)度,第二個(gè)參數(shù)是用來補(bǔ)全的字符串。
{
console.log('x'.padStart(5, 'ab')); // "ababx"
console.log('x'.padStart(4, 'ab')); // 'abax'
console.log('x'.padEnd(5, 'ab')); // "xabab"
console.log('x'.padEnd(4, 'ab')); // "xaba"
}
如果原字符串的長(zhǎng)度,等于或大于最大長(zhǎng)度,則字符串補(bǔ)全不生效,返回原字符串,
{
console.log('xxx'.padStart(2, 'ab')); // "xxx"
console.log('xxx'.padEnd(2, 'ab')); // "xxx"
}
如果用來補(bǔ)全的字符串與原字符串,兩者的長(zhǎng)度之和超過了最大長(zhǎng)度,則會(huì)截取超出位數(shù)的補(bǔ)全字符串。
{
console.log('abc'.padStart(10, '0123456789')); // "0123456abc"
}
如果忽略第二個(gè)參數(shù),默認(rèn)使用空格補(bǔ)全長(zhǎng)度。
{
console.log('x'.padStart(4)); // " x"
console.log('x'.padEnd(4)); // "x "
}
padStart() 的常見用途是為數(shù)值補(bǔ)全指定位數(shù)。
{
console.log('1'.padStart(10, '0')); // "0000000001"
console.log('12'.padStart(10, '0')); // "0000000012"
console.log('123456'.padStart(10, '0')); // "0000123456"
}
另一個(gè)用途是提示字符串格式。
{
console.log('12'.padStart(10, 'YYYY-MM-DD')); // "YYYY-MM-12"
console.log('09-12'.padStart(10, 'YYYY-MM-DD')); // "YYYY-09-12"
}
實(shí)例方法:timeStart(),timeEnd()
Es2019 對(duì)字符串實(shí)例新增了 trimStart() 和 trimEnd() 這兩個(gè)方法。它們的行為與 trim() 一致,trimStart() 消除字符串頭部的空格,trimEnd() 消除尾部的空格。它們返回的都是新字符串,不會(huì)修改原字符串。
trimStart() 只消除頭部的空格,保留尾部的空格。trimEnd() 也是類似行為。
{
const s = ' abc ';
console.log(s.trim()); // "abc"
console.log(s.trimStart()); // "abc "
console.log(s.trimEnd()); // " abc"
}
除了空格鍵,這兩個(gè)方法字符串頭部(或尾部)的 tab 鍵、換行符等不可見的空白符也有效。
瀏覽器還部署了額外的兩個(gè)方法,trimLeft() 是 trimStart() 的別名,trimRight() 是 trimEnd() 的別名。
Es5字符串方法
String.fromCharCode()
String.fromCharCode(Unicode); 從字符編碼創(chuàng)建一個(gè)字符串
實(shí)例方法:toString()
s.toString(args); 返回轉(zhuǎn)換后的字符串。
實(shí)例方法:charAt()
s.charAt(number); 返回指定位置的字符。
實(shí)例方法:charCodeAt()
s.charCodeAt(number); 返回指定位置的字符編碼。
實(shí)例方法:concat()
s.concat(string); 拼接字符串。
實(shí)例方法:indexOf()
s.indexOf(string); 方法返回某個(gè)指定的字符串值在字符串中首次出現(xiàn)的位置。參數(shù)1:必需。規(guī)定需檢索的字符串;參數(shù)2:可選的整數(shù)參數(shù)。規(guī)定在字符串中開始檢索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略該參數(shù),則將從字符串的首字符開始檢索。
實(shí)例方法:lastIndexOf()
s.lastIndexOf(string); 從后向前搜索字符串。
實(shí)例方法:slice()
s.slice(start,end); 截取字符串,返回截取后字符串。1個(gè)參數(shù),從第幾個(gè)開始截取到最后;2個(gè)參數(shù),從第幾個(gè)截取到第幾個(gè)。
實(shí)例方法:split()
s.split(''); 把字符串分割成數(shù)組。不寫參數(shù)就會(huì)分成一個(gè)數(shù)組,有參數(shù)是根據(jù)參數(shù)字符串分割成指定數(shù)組。
實(shí)例方法:substr()
s.substr(start,len); 從指定索引提取字符串中指定數(shù)目的字符串,1個(gè)參數(shù),從第幾個(gè)開始截取到最后;2個(gè)參數(shù),從第幾個(gè)截取幾個(gè)。
實(shí)例方法:substring()
s.substring(start,end); 提取字符串中兩個(gè)指定的索引之間的字符。
實(shí)例方法:toLowerCase()
s.toLowerCase(string); 把字符串轉(zhuǎn)換為小寫。
實(shí)例方法:toUpperCase()
s.toUpperCase(string); 把字符串轉(zhuǎn)換為大寫。
實(shí)例方法:sub()
s.sub() 把字符串顯示為下標(biāo)。
實(shí)例方法:sup
s.sup(); 把字符串顯示為下標(biāo)。
實(shí)例方法:fontcolor()
s.fontcolor(); 使用指定的顏色來顯示字符串。
實(shí)例方法:fontsize()
s.fontsize(); 使用指定的尺寸來顯示字符串。
實(shí)例方法:match()
s.match(); 找到一個(gè)或多個(gè)正則表達(dá)式的匹配,返回一個(gè)數(shù)組對(duì)象,來存儲(chǔ)這個(gè)字符的信息。
實(shí)例方法:replace()
s.replace(); 替換與正則表達(dá)式相匹配的值。
實(shí)例方法:search()
s.search(); 檢索與正則表達(dá)式小匹配的值,返回字符索引。