一.字符串的擴(kuò)展
? ? 1.字符串的Unicode表示法进苍。
? ? 2.codePointAt()
? ? 3.String.fromCodePoint()
? ? 4.字符串的遍歷器接口
? ? 5.normalize()
? ? 6.includes(),startWith(),endsWith()
? ? 7.repeat()
? ? 8.padStart(),padEnd()
? ? 9.matchAll()
? ? 10.模板字符串
? ? 11.實(shí)例:模板編譯
? ? 12. 標(biāo)簽?zāi)0?/p>
? ? 13.String.raw()
? ? 14.模板字符串的限制
(1)字符串的Unicode表示法
? ? ? ? JavaScript允許采用\uxxxx形式表示一個字符灶体,其中xxxx表示字符串的Unicode碼點(diǎn)疙筹。
? ? ? ? '\u0061' //a
? ? ? ? 但是這種表示法只限于碼點(diǎn)在\u0000~\uFFFF之間的字符。超出這個范圍的自符,必須使用兩個雙字節(jié)的形式表示。
? ? ? ? '\u20BB7' // ' 7'
? ? ? ? 上面代碼表示,如果直接在\u后面跟上超過0xFFFF的數(shù)值(比如\u20BB7)垒棋,JavaScript會理解成|\u20BB+7.由于\u20BB是一個不可打印的字符串,所以只會顯示一個空格余指,后面跟著一個7.
? ? ? ? ES6對這一點(diǎn)做出了改進(jìn)捕犬,只要將碼點(diǎn)放入大括號,就能正確解讀該字符串酵镜。
? ??????"\u{20BB7}"http:// "??"
????????"\u{41}\u{42}\u{43}"http:// "ABC"
????????lethello=123;hell\u{6F} // 123
????????'\u{1F680}'==='\uD83D\uDE80'// true
? ? ? ? 上面代碼中碉碉,最后一個例子表明,大括號表示法與四字節(jié)的UTF-16編碼等價的淮韭。
(2)codePointAt()
? ? ? ? Javascript內(nèi)部垢粮,字符串以UTF-16的格式儲存,每個字符固定為2個字節(jié)靠粪。對于那些需要4個字節(jié)儲存的字符(Unicode碼點(diǎn)大于0xFFFF的字符)蜡吧,Jvascript會認(rèn)為它們是兩個字符。
上面代碼中占键,漢字‘??’的碼點(diǎn)是0x20BB7昔善,UTF-16編碼為0xD842 0xDFB7(十進(jìn)制55362 57271),需要四個字節(jié)存儲畔乙。對于這種4個字節(jié)的字符君仆,JavaScript不能正確處理,字符串長度會誤判為2牲距,而且chartAt方法無法讀取整個字符返咱,chartCodeAt方法只能分別返回前兩個字節(jié)和后兩個字節(jié)的值。
ES6提供了codePointAt方法牍鞠,能夠正確處理4個字節(jié)存儲的字符咖摹,返回一個字符的碼點(diǎn)。
codePointAt方法的參數(shù)难述,是字符串在字符串中的位置(從0開始)萤晴。上面代碼中吐句,JavaScript將“??a”視為三個字符,codePointAt方法在第一個字符上店读,正確的識別了“??”蕴侧,返回了它的十進(jìn)制碼點(diǎn)134071(即十六進(jìn)制的20BB7)。在第二個字符(即“??”的后兩個字節(jié))和第三個字符”a“上两入,codePointAt方法的結(jié)果與chartCodeAt方法相同∏貌牛總之裹纳,codePointAt方法會正確返回 32 位的 UTF-16 字符的碼點(diǎn)。對于那些兩個字節(jié)儲存的常規(guī)字符紧武,它的返回結(jié)果與charCodeAt方法相同剃氧。
codePointAt方法返回的是碼點(diǎn)的十進(jìn)制值,如果想要十六進(jìn)制的值阻星,可以使用toString方法轉(zhuǎn)換一下朋鞍。
你可能注意到了,codePointAt方法的參數(shù)妥箕,仍然是不正確的滥酥。比如,上面代碼中畦幢,字符a在字符串s的正確位置序號應(yīng)該是 1坎吻,但是必須向codePointAt方法傳入 2。解決這個問題的一個辦法是使用for...of循環(huán)宇葱,因?yàn)樗鼤_識別 32 位的 UTF-16 字符瘦真。
codePointAt方法是測試一個字符由兩個字節(jié)還是由四個字節(jié)組成的最簡單方法。
(3)String.fromCodePoint()
? ?ES5提供stirng.fromCharCode方法黍瞧,用于從碼點(diǎn)返回對應(yīng)的字符诸尽,但是這個方法不能識別32位的UTF-16字符(Unicode編號大于0xFFFF)。
? ? String.fromCharCode(0x20BB7) //"?"
上面代碼中印颤,String.fromCharCode不能識別大于0xFFFF的碼點(diǎn)您机,所以0x20BB7就發(fā)生了溢出,最高位2被舍棄膀哲,最后返回碼點(diǎn)U+0BB7對應(yīng)的字符往产,而不是碼點(diǎn)u+20BB7對應(yīng)的字符。
ES6提供了String.fromCodePoint方法某宪,可以識別大于0xFFFF的字符仿村,彌補(bǔ)了String.fromCharCode方法的不足。在作用上兴喂,正好與codePoint方法相反蔼囊。
上面的代碼中焚志,如果String.fromCodePoint方法有多個參數(shù),則它們會被合并成一個字符串返回畏鼓。注意酱酬,fromCodePoint方法定義在String對象上,兒codePointAt方法定義在字符串的實(shí)例的實(shí)例對象上云矫。
*charAt()方法可返回指定位置的字符膳沽。stringObject.charAt(index),index必需让禀,表示字符串中某個位置的數(shù)字挑社,即字符串在字符串中的下標(biāo)。字符串中第一個字符的下標(biāo)是0巡揍,如果參數(shù)index不在0與string.length之間痛阻,該方法將返回一個空字符串。
*charCodeAt()方法可返回指定位置的字符的Unicode編碼腮敌。stringObject.charCodeAt(index)這個返回值是0-65535之間的整數(shù)阱当。方法charCodeAt()方法與chartAt()方法執(zhí)行的操作相似,只不過前者返回的是位于指定位置的字符的編碼糜工,而后者返回的是字符子串弊添。
*fromCharCode()可接受一個指定的Unicode值,然后返回一個字符串啤斗。String.fromCharCode(numX,numX,...,numX)表箭。numX必需,一個或多個Unicode值钮莲,即要創(chuàng)建的字符串中的字符串的Unicode編碼免钻。
(4)字符串的遍歷器接口
? ? ES6為字符串添加了遍歷器接口,使得字符串可以被for...of循環(huán)遍歷崔拥。
除了遍歷字符串极舔,這個遍歷器最大的優(yōu)點(diǎn)是可以識別大于0xFFFF的碼點(diǎn),傳統(tǒng)的for...循環(huán)無法識別這樣的碼點(diǎn)链瓦。
(5)normalize()
? ? ? ? 許多歐洲語言有語調(diào)符號和重音符號拆魏。為了表示它們,Unicode提供了兩種方法慈俯。一種是直接提供帶重音符號的字符渤刃,
比如ǒ(\u01D1)。另一種是提供合成符號(combining character)贴膘,即原字符與重音符號的合成卖子,兩個字符合成一個字符,比如O(\u004F)和ˇ(\u030C)合成ǒ(\u004F\u030C)刑峡。
這兩種表示方法洋闽,在視覺和語義上都等價玄柠,但是 JavaScript 不能識別。
'\u01D1'==='\u004F\u030C' //false'\u01D1'.length // 1'\u004F\u030C'.length // 2
ES6 提供字符串實(shí)例的normalize()方法诫舅,用來將字符的不同表示方法統(tǒng)一為同樣的形式羽利,這稱為 Unicode 正規(guī)化。
'\u01D1'.normalize()==='\u004F\u030C'.normalize()// true
?(6)includes(),startsWith(),endsWith()
? ? ? ? ?傳統(tǒng)上刊懈,Javascript只有indexOf方法这弧,可以用來確定一個字符串是否包含在另一個字符串中。ES6又提供了三種新的方法虚汛。
? ? ? ? ? ? -includes():返回布爾值当宴,表示是否找到了參數(shù)字符串。
? ? ? ? ? ? -startWith():返回布爾值泽疆,表示參數(shù)字符串是否在原始字符串的頭部。
? ? ? ? ? ? -endWith():返回布爾值玲献,表示參數(shù)字符串是否在原字符串的尾部殉疼。
? ? ? ? 這三個方法都支持第二個參數(shù),表示開始搜索的位置捌年。
上面的代碼表示瓢娜,使用第二個參數(shù)n時,endsWith的行為與其它兩個方法有所不同礼预。他針對前n個字符眠砾,而其它兩個方法針對從第n個位置直到字符串結(jié)束。
(7)repeat()
? ? ? ? repeat方法返回一個新字符串托酸,表示將原字符串重復(fù)n次褒颈。
? ??????'x'.repeat(3) // "xxx"'hello'.repeat(2) // "hellohello"'na'.repeat(0) // ""
? ? ? ? 參數(shù)如果是小數(shù),會被取整励堡。
????????'na'.repeat(2.9) // "nana"
? ? ? ? 如果repeat的參數(shù)是負(fù)數(shù)或則infinity谷丸,會報錯,但是如果參數(shù)是0到1之間的小數(shù)应结,的等同于0刨疼,這是因?yàn)闀冗M(jìn)行取整運(yùn)算。0到-1之間的小數(shù)鹅龄,取整以后等于-0揩慕,repeat視同為0.參數(shù)NaN等同于 0。
(8)padStart()扮休,padEnd()
? ? ? ? ES2017引入了字符串不穿長度功能迎卤。如果某個字符串不夠指定長度,會在頭部或則尾部補(bǔ)全肛炮。padStart()用于頭部補(bǔ)全止吐,padEnd()用于尾部補(bǔ)全宝踪。
上面的代碼中,padStart和padEnd一共接受兩個參數(shù)碍扔,第一個參數(shù)用來指定字符串的最小長度瘩燥,第二個參數(shù)是用來補(bǔ)全的字符串。
如果原字符串的長度不同,等于或大于指定的最小長度厉膀,則會返回原字符串。
如果用來補(bǔ)全的字符串與原字符串兩者的長度之和超過了指定的最小長度二拐,則會截去超出位數(shù)的補(bǔ)全字符串服鹅。
如果省略第二個參數(shù),默認(rèn)使用空格補(bǔ)全長度百新。
padStart的常見用途是為數(shù)值補(bǔ)全指定位數(shù)企软。下面代碼生成 10 位的數(shù)值字符串。
'1'.padStart(10,'0') // "0000000001"
'12'.padStart(10,'0') // "0000000012"
'123456'.padStart(10,'0') // "0000123456"
另一個用途是提示字符串格式饭望。
'12'.padStart(10,'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10,'YYYY-MM-DD') // "YYYY-09-12"
(9)matchAll()
matchAll方法返回一個正則表達(dá)式在當(dāng)前字符串的所有匹配仗哨,詳見《正則的擴(kuò)展》的一章。
(10)模板字符串
? ? ? ? 傳統(tǒng)的JavaScript語言铅辞,輸出模板通常是這樣寫的厌漂。
上面這種寫法相當(dāng)繁瑣不方便,ES6引入了模板字符串解決這個問題斟珊。
如果使用模板字符串表示多行字符串苇倡,所有的空格和縮進(jìn)都會被保留在輸出中。如果你不想要這個換行囤踩,可以使用trim方法消除它旨椒。
模板字符串中嵌入變量,需要將變量名寫在${}之中堵漱。大括號內(nèi)部可以放入任意的 JavaScript 表達(dá)式钩乍,可以進(jìn)行運(yùn)算,以及引用對象屬性怔锌。
模板字符串之中還能調(diào)用函數(shù)寥粹。
如果大括號中的值不是字符串,將按照一般的規(guī)則轉(zhuǎn)為字符串埃元。比如涝涤,大括號中是一個對象,將默認(rèn)調(diào)用對象的toString方法岛杀。
如果需要引用模板字符串本身阔拳,在需要時執(zhí)行,可以像下面這樣寫。
(11)模板標(biāo)簽
上面代碼中,模板字符串前面有一個標(biāo)識名tag货裹,它是一個函數(shù)嗤形。整個表達(dá)式的返回值,就是tag函數(shù)處理模板字符串后的返回值弧圆。函數(shù)tag依次會接收到多個參數(shù)赋兵。tag函數(shù)的第一個參數(shù)就是一個數(shù)組,該數(shù)組的成員是模板字符串中那些沒有變量替換的部分搔预,也就是說霹期,變量替換只發(fā)生在數(shù)組的也就是說,變量替換只發(fā)生在數(shù)組的第一個成員與第二個成員之間拯田、第二個成員與第三個成員之間历造,以此類推。tag函數(shù)的其他參數(shù)船庇,都是模板字符串各個變量被替換后的值帕膜。
????????????????????????第二中passthru函數(shù)寫法。
“標(biāo)簽?zāi)0濉钡囊粋€重要應(yīng)用溢十,就是過濾 HTML 字符串,防止用戶輸入惡意內(nèi)容达吞。
上面的代碼中张弛,sender變量往往是用戶提供的,經(jīng)過SafeHTML函數(shù)處理酪劫,里面的特殊字符都會被轉(zhuǎn)義吞鸭。
(12)String.raw().
? ? ES6還為原生String對象,提供了一個raw方法覆糟。
? ? String.raw方法刻剥,往往用來充當(dāng)模板字符串的處理函數(shù),返回一個斜杠都被轉(zhuǎn)義(即斜杠前面再加一個斜杠)的字符串滩字,對應(yīng)于替換變量后的模板字符串造虏。
如果原字符串的斜杠已經(jīng)轉(zhuǎn)義,那么String.raw會進(jìn)行再次轉(zhuǎn)義麦箍。
String.raw方法可以作為處理模板字符串的基本方法漓藕,它會將所有變量替換,而且對斜杠進(jìn)行轉(zhuǎn)義挟裂,方便下一步作為字符串來使用享钞。
String.raw方法也可以作為正常的函數(shù)使用。這時诀蓉,它的第一個參數(shù)栗竖,應(yīng)該是一個具有raw屬性的對象暑脆,且raw屬性的值應(yīng)該是一個數(shù)組。
二 正則的擴(kuò)展
2.字符串的正則方法
3.u 修飾符
5.y 修飾符
9.后行斷言
10.Unicode 屬性類
11.具名組匹配
(1)RegExp構(gòu)造函數(shù)
? ? ? ? 在ES5中狐肢,RegExp構(gòu)造函數(shù)的參數(shù)有兩種情況添吗。
? ? ? ? 第一種情況是,參數(shù)是字符串处坪,這時第二個參數(shù)表示正則表達(dá)式的修飾符
? ? ? ? 1.var regex = new RegExp('xyz','i');(1,2相等)
? ? ? ? 2.var regex = /xyz/i;
? ? ? ? 第二種情況是根资,參數(shù)是一個正則表達(dá)式,這時會返回一個原有正則表達(dá)式的拷貝同窘。
????????varregex=newRegExp(/xyz/i);// 等價于varregex=/xyz/i;
????????但是玄帕,ES5 不允許此時使用第二個參數(shù)添加修飾符,否則會報錯想邦。
????????varregex=newRegExp(/xyz/,'i');
????????ES6 改變了這種行為裤纹。如果RegExp構(gòu)造函數(shù)第一個參數(shù)是一個正則對象,那么可以使用第二個參數(shù)指定修飾符丧没。而且鹰椒,返回的正則表達(dá)式會忽略原有的正則表達(dá)式的修飾符,只使用新指定的修飾符呕童。
????????newRegExp(/abc/ig,'i').flags
上面代碼中漆际,原有正則對象的修飾符是ig,它會被第二個參數(shù)i覆蓋夺饲。