资讯专栏INFORMATION COLUMN

ES6学习摘要(03)(新人学习)

番茄西红柿 / 1082人阅读

摘要:字符的表示法允许采用形式表示一个字符,其中表示字符的码点。方法,用来将字符的不同表示方法统一为同样的形式,这称为正规化。,默认参数,表示标准等价合成,返回多个简单字符的合成字符。返回布尔值,表示参数字符串是否在原字符串的头部。

ECMAScript6/ES6 入门

let和const命令
变量的解构赋值

五、字符串的扩展

注:这章没什么可以理解的,看过一遍就行,所以大体上我把有用的一些东西拷过来给大家看下。
1、字符的Unicode表示法
JavaScript 允许采用uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。但是,这种表示法只限于码点在u0000~uFFFF之间的字符。超出这个范围的字符,必须用两个双字节的形式表示。如果直接在u后面跟上超过0xFFFF的数值(比如u20BB7),JavaScript 会理解成u20BB+7。由于u20BB是一个不可打印字符,所以只会显示一个空格,后面跟着一个7。

</>复制代码

  1. "uD842uDFB7"
  2. // "?"
  3. "u20BB7"
  4. // " 7"

在ES6中做了处理,只要将码点放入大括号,就能正确解读该字符。有了这种表示法之后,JavaScript 共有 6 种方法可以表示一个字符。

</>复制代码

  1. "u{20BB7}"
  2. // "?"
  3. "u{41}u{42}u{43}"
  4. // "ABC"
  5. let hello = 123;
  6. hellu{6F} // 123
  7. "u{1F680}" === "uD83DuDE80"
  8. // true

</>复制代码

  1. "z" === "z" // true
  2. "172" === "z" // true
  3. "x7A" === "z" // true
  4. "u007A" === "z" // true
  5. "u{7A}" === "z" // true

2、codePointAt()
对于原来的charAtcharCodeAt,是无法获取4个字节的字符串的,charCodeAt方法只能分别返回前两个字节和后两个字节的值。而有些汉字是需要4个字节的,比如:汉字“?”(注意,这个字不是“吉祥”的“吉”)的码点是0x20BB7

</>复制代码

  1. var s = "?";
  2. s.length // 2
  3. s.charAt(0) // ""
  4. s.charAt(1) // ""
  5. s.charCodeAt(0) // 55362
  6. s.charCodeAt(1) // 57271

所以在ES6中提供了codePointAt方法,能够正确返回4个字节存储的字符串。

</>复制代码

  1. let s = "?a";
  2. s.codePointAt(0) // 134071
  3. s.codePointAt(1) // 57271
  4. s.codePointAt(2) // 97

有的人就要问了,codePointAt方法为啥是3个字符(0,1,2)?首先,JavaScript肯定是将"?a"视作3个字符的,只是ES6方法不同而已,codePointAt(0)返回的是第一字符"?",codePointAt(1)返回的是"?"(共4个字节)的后两个字节,codePointAt(2)返回的是"a"。也就是说后两个字节,codePointAt方法的结果与charCodeAt方法相同。
同时,从上面的例子可以看出,codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。

</>复制代码

  1. let s = "?a";
  2. s.codePointAt(0).toString(16) // "20bb7"
  3. s.codePointAt(2).toString(16) // "61"

可能这样看上去感觉怪怪的,毕竟只有两个字符,写的时候还要去注意0,2,其实有更好的解决办法,利用for...of循环,直接看例子:

</>复制代码

  1. let s = "?a";
  2. for (let ch of s) {
  3. console.log(ch.codePointAt(0).toString(16));
  4. }
  5. // 20bb7
  6. // 61

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

</>复制代码

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

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

</>复制代码

  1. String.fromCodePoint(0x20BB7)
  2. // "?"
  3. String.fromCodePoint(0x78, 0x1f680, 0x79) === "xuD83DuDE80y"
  4. // true

4、字符串的遍历器接口

</>复制代码

  1. for (let codePoint of "foo") {
  2. console.log(codePoint)
  3. }
  4. // "f"
  5. // "o"
  6. // "o"

for...of循环遍历,这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点。
5、at()
同上,charAt不能识别码点大于0xFFFF的字符。at则可以。

</>复制代码

  1. "abc".at(0) // "a"
  2. "?".at(0) // "?"

6、normalize()
normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。
许多欧洲语言有语调符号和重音符号。为了表示它们,Unicode 提供了两种方法。一种是直接提供带重音符号的字符,比如Ǒ(u01D1)。另一种是提供合成符号(combining character),即原字符与重音符号的合成,两个字符合成一个字符,比如O(u004F)ˇ(u030C)合成Ǒ(u004Fu030C)

</>复制代码

  1. "u01D1"==="u004Fu030C" //false
  2. "u01D1".normalize() === "u004Fu030C".normalize()
  3. // true

</>复制代码

  1. normalize方法可以接受一个参数来指定normalize的方式,参数的四个可选值如下。
  2. NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
  3. NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
  4. NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
  5. NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。

7、includes(), startsWith(), endsWith()
indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。

</>复制代码

  1. includes():返回布尔值,表示是否找到了参数字符串。
  2. startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  3. endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

</>复制代码

  1. let s = "Hello world!";
  2. s.startsWith("Hello") // true
  3. s.endsWith("!") // true
  4. s.includes("o") // true

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

</>复制代码

  1. let s = "Hello world!";
  2. s.startsWith("world", 6) // true
  3. s.endsWith("Hello", 5) // true
  4. s.includes("Hello", 6) // false

8、repeat()
repeat方法返回一个新字符串,表示将原字符串重复n次。参数如果是小数,会被取整。如果repeat的参数是负数或者Infinity,会报错。

</>复制代码

  1. "x".repeat(3) // "xxx"
  2. "na".repeat(2.9) // "nana"
  3. "na".repeat(0) // ""
  4. "na".repeat(Infinity)
  5. // RangeError
  6. "na".repeat(-1)
  7. // RangeError

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

</>复制代码

  1. "na".repeat(-0.9) // ""

参数NaN等同于 0。

</>复制代码

  1. "na".repeat(NaN) // ""

如果repeat的参数是字符串,则会先转换成数字。

</>复制代码

  1. "na".repeat("na") // ""
  2. "na".repeat("3") // "nanana"

9、padStart(),padEnd()
如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

</>复制代码

  1. "x".padStart(5, "ab") // "ababx"
  2. "x".padStart(4, "ab") // "abax"
  3. "x".padEnd(5, "ab") // "xabab"
  4. "x".padEnd(4, "ab") // "xaba"

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

</>复制代码

  1. "xxx".padStart(2, "ab") // "xxx"
  2. "xxx".padEnd(2, "ab") // "xxx"

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

</>复制代码

  1. "x".padStart(4) // " x"
  2. "x".padEnd(4) // "x "

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

</>复制代码

  1. "1".padStart(10, "0") // "0000000001"
  2. "12".padStart(10, "0") // "0000000012"
  3. "123456".padStart(10, "0") // "0000123456"

10、模板字符串
用反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

</>复制代码

  1. // 普通字符串
  2. `In JavaScript "
  3. " is a line-feed.`
  4. // 多行字符串
  5. `In JavaScript this is
  6. not legal.`
  7. console.log(`string text line 1
  8. string text line 2`);
  9. // 字符串中嵌入变量
  10. let name = "Bob", time = "today";
  11. `Hello ${name}, how are you ${time}?`

11、实例:模板编译

</>复制代码

  1. let template = `
    • <% for(let i=0; i < data.supplies.length; i++) { %>
    • <%= data.supplies[i] %>
    • <% } %>
  2. `;

上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置 JavaScript 代码,使用<%= ... %>输出 JavaScript 表达式。
怎么编译这个模板字符串呢?

一种思路是将其转换为 JavaScript 表达式字符串。

</>复制代码

  1. echo("
      ");
    • for(let i=0; i < data.supplies.length; i++) {
    • echo("
    • ");
    • echo(data.supplies[i]);
    • echo("
    • ");
    • };
    • echo("
    ");

这个转换使用正则表达式就行了。

</>复制代码

  1. let evalExpr = /<%=(.+?)%>/g;
  2. let expr = /<%([sS]+?)%>/g;
  3. template = template
  4. .replace(evalExpr, "`);
  5. echo( $1 );
  6. echo(`")
  7. .replace(expr, "`);
  8. $1
  9. echo(`");
  10. template = "echo(`" + template + "`);";

然后,将template封装在一个函数里面返回,就可以了。

</>复制代码

  1. let script =
  2. `(function parse(data){
  3. let output = "";
  4. function echo(html){
  5. output += html;
  6. }
  7. ${ template }
  8. return output;
  9. })`;
  10. return script;

将上面的内容拼装成一个模板编译函数compile。

</>复制代码

  1. function compile(template){
  2. const evalExpr = /<%=(.+?)%>/g;
  3. const expr = /<%([sS]+?)%>/g;
  4. template = template
  5. .replace(evalExpr, "`);
  6. echo( $1 );
  7. echo(`")
  8. .replace(expr, "`);
  9. $1
  10. echo(`");
  11. template = "echo(`" + template + "`);";
  12. let script =
  13. `(function parse(data){
  14. let output = "";
  15. function echo(html){
  16. output += html;
  17. }
  18. ${ template }
  19. return output;
  20. })`;
  21. return script;
  22. }

compile函数的用法如下。

</>复制代码

  1. let parse = eval(compile(template));
  2. div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner" ] });
  3. //
    • //
    • broom
    • //
    • mop
    • //
    • cleaner
    • //

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

</>复制代码

  1. String.raw`Hi
  2. ${2+3}!`;
  3. // "Hi
  4. 5!"
  5. String.raw`Hiu000A!`;
  6. // "Hiu000A!"

如果原字符串的斜杠已经转义,那么String.raw不会做任何处理。

</>复制代码

  1. String.raw`Hi
  2. `
  3. // "Hi
  4. "

String.raw的代码基本如下。

</>复制代码

  1. String.raw = function (strings, ...values) {
  2. let output = "";
  3. let index;
  4. for (index = 0; index < values.length; index++) {
  5. output += strings.raw[index] + values[index];
  6. }
  7. output += strings.raw[index]
  8. return output;
  9. }

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

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

</>复制代码

  1. String.raw({ raw: "test" }, 0, 1, 2);
  2. // "t0e1s2t"

// 等同于

</>复制代码

  1. String.raw({ raw: ["t","e","s","t"] }, 0, 1, 2);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92248.html

相关文章

  • ES6学习摘要(01)(新人学习

    摘要:入门一前言由于最近本人在学习,做一些笔记能够更好的熟悉,就趁此机会来写一篇关于的新人学习摘要吧。的作用域与命令相同只在声明所在的块级作用域内有效。块级作用域新增方式和实际上为新增了块级作用域。同时,函数声明还会提升到所在的块级作用域的头部。 ECMAScript6/ES6 入门 一、前言 由于最近本人在学习ES6,做一些笔记能够更好的熟悉,就趁此机会来写一篇关于ES6的新人学习摘要吧。...

    dmlllll 评论0 收藏0
  • ES6学习摘要(02)(新人学习

    摘要:默认值同时,对象解构赋值也允许设置默认值,默认值生效的判断条件同数组,只有在对应值严格等于时会生效。报错如果要将一个已经声明的变量用于解构赋值,必须非常小心。的规则是,只要有可能导致解构的歧义,就不得使用圆括号。 ECMAScript6/ES6 入门 let和const命令 四、变量的解构赋值 在ES6之前,数组和对象属性赋值只能直接指定固定值,ES6 允许按照一定模式,从数组和对象中...

    Jonathan Shieber 评论0 收藏0
  • 2017前端现状--答题救不了前端新人

    摘要:众所周知,前端近几年闹了一场革命。这些问题反应了什么现象确实前端很火,引来了一批批新人。前端小白们如火如荼的学习着现在前端流行的新技术栈。写在最后所以啊,在目睹了很多白痴问题后,我终于发出了一声呐喊,答题救不了前端新人。 众所周知,前端近几年闹了一场革命。前端在编程领域也掀起了学习潮。至少在中国,从2013年下半年至今,在搜索指数上,有着爆炸式的增长。可以看下数据:百度指数,Googl...

    jone5679 评论0 收藏0
  • 2017前端现状--答题救不了前端新人

    摘要:众所周知,前端近几年闹了一场革命。这些问题反应了什么现象确实前端很火,引来了一批批新人。前端小白们如火如荼的学习着现在前端流行的新技术栈。写在最后所以啊,在目睹了很多白痴问题后,我终于发出了一声呐喊,答题救不了前端新人。 众所周知,前端近几年闹了一场革命。前端在编程领域也掀起了学习潮。至少在中国,从2013年下半年至今,在搜索指数上,有着爆炸式的增长。可以看下数据:百度指数,Googl...

    alogy 评论0 收藏0
  • 刚进入软件测试行业的新人,这些宝贵经验要收好~

    摘要:软件测试从宏观上可以分为功能测试性能测试安全性测试三个方面,如果能将三者结合起来就说明已经将这个岗位做的十分好了。 恍然间,发现自己已经在这个行业五年之久,回顾过往,思绪良多,一路走来,或多或少都经历过一些坎坷,也碰到过不少大大小小的困难。在此就不多加叙述了。 本篇文章主要想写给刚入门的测...

    马永翠 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<