ES6扩展

一.字符串的扩展

    1.字符串的Unicode表示法。

    2.codePointAt()

    3.String.fromCodePoint()

    4.字符串的遍历器接口

    5.normalize()

    6.includes(),startWith(),endsWith()

    7.repeat()

    8.padStart(),padEnd()

    9.matchAll()

    10.模板字符串

    11.实例:模板编译

    12. 标签模板

    13.String.raw()

    14.模板字符串的限制

(1)字符串的Unicode表示法

        JavaScript允许采用\uxxxx形式表示一个字符,其中xxxx表示字符串的Unicode码点。

        '\u0061' //a

        但是这种表示法只限于码点在\u0000~\uFFFF之间的字符。超出这个范围的自符,必须使用两个双字节的形式表示。

        '\u20BB7' // ' 7'

        上面代码表示,如果直接在\u后面跟上超过0xFFFF的数值(比如\u20BB7),JavaScript会理解成|\u20BB+7.由于\u20BB是一个不可打印的字符串,所以只会显示一个空格,后面跟着一个7.

        ES6对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符串。

        "\u{20BB7}"// "𠮷"

        "\u{41}\u{42}\u{43}"// "ABC"

        lethello=123;hell\u{6F} // 123

        '\u{1F680}'==='\uD83D\uDE80'// true

        上面代码中,最后一个例子表明,大括号表示法与四字节的UTF-16编码等价的。

(2)codePointAt()

        Javascript内部,字符串以UTF-16的格式储存,每个字符固定为2个字节。对于那些需要4个字节储存的字符(Unicode码点大于0xFFFF的字符),Jvascript会认为它们是两个字符。

上面代码中,汉字‘𠮷’的码点是0x20BB7,UTF-16编码为0xD842 0xDFB7(十进制55362 57271),需要四个字节存储。对于这种4个字节的字符,JavaScript不能正确处理,字符串长度会误判为2,而且chartAt方法无法读取整个字符,chartCodeAt方法只能分别返回前两个字节和后两个字节的值。

ES6提供了codePointAt方法,能够正确处理4个字节存储的字符,返回一个字符的码点。

codePointAt方法的参数,是字符串在字符串中的位置(从0开始)。上面代码中,JavaScript将“𠮷a”视为三个字符,codePointAt方法在第一个字符上,正确的识别了“𠮷”,返回了它的十进制码点134071(即十六进制的20BB7)。在第二个字符(即“𠮷”的后两个字节)和第三个字符”a“上,codePointAt方法的结果与chartCodeAt方法相同。总之,codePointAt方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt方法相同。

codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。

你可能注意到了,codePointAt方法的参数,仍然是不正确的。比如,上面代码中,字符a在字符串s的正确位置序号应该是 1,但是必须向codePointAt方法传入 2。解决这个问题的一个办法是使用for...of循环,因为它会正确识别 32 位的 UTF-16 字符。

codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。

(3)String.fromCodePoint()

   ES5提供stirng.fromCharCode方法,用于从码点返回对应的字符,但是这个方法不能识别32位的UTF-16字符(Unicode编号大于0xFFFF)。

    String.fromCharCode(0x20BB7) //"ஷ"

上面代码中,String.fromCharCode不能识别大于0xFFFF的码点,所以0x20BB7就发生了溢出,最高位2被舍弃,最后返回码点U+0BB7对应的字符,而不是码点u+20BB7对应的字符。

ES6提供了String.fromCodePoint方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode方法的不足。在作用上,正好与codePoint方法相反。

上面的代码中,如果String.fromCodePoint方法有多个参数,则它们会被合并成一个字符串返回。注意,fromCodePoint方法定义在String对象上,儿codePointAt方法定义在字符串的实例的实例对象上。

*charAt()方法可返回指定位置的字符。stringObject.charAt(index),index必需,表示字符串中某个位置的数字,即字符串在字符串中的下标。字符串中第一个字符的下标是0,如果参数index不在0与string.length之间,该方法将返回一个空字符串。

*charCodeAt()方法可返回指定位置的字符的Unicode编码。stringObject.charCodeAt(index)这个返回值是0-65535之间的整数。方法charCodeAt()方法与chartAt()方法执行的操作相似,只不过前者返回的是位于指定位置的字符的编码,而后者返回的是字符子串。

*fromCharCode()可接受一个指定的Unicode值,然后返回一个字符串。String.fromCharCode(numX,numX,...,numX)。numX必需,一个或多个Unicode值,即要创建的字符串中的字符串的Unicode编码。

(4)字符串的遍历器接口

    ES6为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历。

除了遍历字符串,这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for...循环无法识别这样的码点。

(5)normalize()

        许多欧洲语言有语调符号和重音符号。为了表示它们,Unicode提供了两种方法。一种是直接提供带重音符号的字符,

比如Ǒ(\u01D1)。另一种是提供合成符号(combining character),即原字符与重音符号的合成,两个字符合成一个字符,比如O(\u004F)和ˇ(\u030C)合成Ǒ(\u004F\u030C)。

这两种表示方法,在视觉和语义上都等价,但是 JavaScript 不能识别。

'\u01D1'==='\u004F\u030C' //false'\u01D1'.length // 1'\u004F\u030C'.length // 2

ES6 提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

'\u01D1'.normalize()==='\u004F\u030C'.normalize()// true

 (6)includes(),startsWith(),endsWith()

         传统上,Javascript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新的方法。

            -includes():返回布尔值,表示是否找到了参数字符串。

            -startWith():返回布尔值,表示参数字符串是否在原始字符串的头部。

            -endWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

        这三个方法都支持第二个参数,表示开始搜索的位置。

上面的代码表示,使用第二个参数n时,endsWith的行为与其它两个方法有所不同。他针对前n个字符,而其它两个方法针对从第n个位置直到字符串结束。

(7)repeat()

        repeat方法返回一个新字符串,表示将原字符串重复n次。

        'x'.repeat(3) // "xxx"'hello'.repeat(2) // "hellohello"'na'.repeat(0) // ""

        参数如果是小数,会被取整。

        'na'.repeat(2.9) // "nana"

        如果repeat的参数是负数或则infinity,会报错,但是如果参数是0到1之间的小数,的等同于0,这是因为会先进行取整运算。0到-1之间的小数,取整以后等于-0,repeat视同为0.参数NaN等同于 0。


(8)padStart(),padEnd()

        ES2017引入了字符串不穿长度功能。如果某个字符串不够指定长度,会在头部或则尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

上面的代码中,padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

如果原字符串的长度,等于或大于指定的最小长度,则会返回原字符串。

如果用来补全的字符串与原字符串两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。

如果省略第二个参数,默认使用空格补全长度。

padStart的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串。

'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方法返回一个正则表达式在当前字符串的所有匹配,详见《正则的扩展》的一章。

(10)模板字符串

        传统的JavaScript语言,输出模板通常是这样写的。

上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题。

如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出中。如果你不想要这个换行,可以使用trim方法消除它。

模板字符串中嵌入变量,需要将变量名写在${}之中。大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。

模板字符串之中还能调用函数。

如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。

如果需要引用模板字符串本身,在需要时执行,可以像下面这样写。

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

(11)模板标签

上面代码中,模板字符串前面有一个标识名tag,它是一个函数。整个表达式的返回值,就是tag函数处理模板字符串后的返回值。函数tag依次会接收到多个参数。tag函数的第一个参数就是一个数组,该数组的成员是模板字符串中那些没有变量替换的部分,也就是说,变量替换只发生在数组的也就是说,变量替换只发生在数组的第一个成员与第二个成员之间、第二个成员与第三个成员之间,以此类推。tag函数的其他参数,都是模板字符串各个变量被替换后的值。

                        第二中passthru函数写法。

“标签模板”的一个重要应用,就是过滤 HTML 字符串,防止用户输入恶意内容。

上面的代码中,sender变量往往是用户提供的,经过SafeHTML函数处理,里面的特殊字符都会被转义。

(12)String.raw().

    ES6还为原生String对象,提供了一个raw方法。

    String.raw方法,往往用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字符串。

如果原字符串的斜杠已经转义,那么String.raw会进行再次转义。

String.raw方法可以作为处理模板字符串的基本方法,它会将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用。

String.raw方法也可以作为正常的函数使用。这时,它的第一个参数,应该是一个具有raw属性的对象,且raw属性的值应该是一个数组。

二 正则的扩展

1.RegExp 构造函数

2.字符串的正则方法

3.u 修饰符

4.RegExp.prototype.unicode 属性

5.y 修饰符

6.RegExp.prototype.sticky 属性

7.RegExp.prototype.flags 属性

8.s 修饰符:dotAll 模式

9.后行断言

10.Unicode 属性类

11.具名组匹配

12.String.prototype.matchAll

(1)RegExp构造函数

        在ES5中,RegExp构造函数的参数有两种情况。

        第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符

        1.var regex = new RegExp('xyz','i');(1,2相等)

        2.var regex = /xyz/i;

        第二种情况是,参数是一个正则表达式,这时会返回一个原有正则表达式的拷贝。

        varregex=newRegExp(/xyz/i);// 等价于varregex=/xyz/i;

        但是,ES5 不允许此时使用第二个参数添加修饰符,否则会报错。

        varregex=newRegExp(/xyz/,'i');

        ES6 改变了这种行为。如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。

        newRegExp(/abc/ig,'i').flags

上面代码中,原有正则对象的修饰符是ig,它会被第二个参数i覆盖。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270