欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

理解ES6 (1) var, let, const 之间的区别 (2) 字符串和正则表达式

程序员文章站 2022-06-13 10:02:56
...

英文电子书点此阅读《understanding es6》

目录

block bindings

es6中引进了let和const,需要注意的地方如下:

  1. block binding是指function或者{}。let 和 const 声明的变量不会提升,只在被声明之后才存在。在这之前变量处于时间死亡域中(tdz: temporal dead zone),甚至不能用貌似安全的操作符诸如typeof 来获取。
  2. let 和 const 在循环中与var不一样。for in 和 for of 都在每一次循环的iteration中生成了一个新的引用。因此,在循环体中生成的函数可以获取到当前迭代(interation)中的引用值,而不是循环之后的最终值。let在for循环中也是同理,但const不能用于for循环,因为改变了变量值。
  3. 用let或者const声明的变量,不能在该作用域下再次声明。let可以改变其值,const不能改变。const了就是常量了!
  4. 块级绑定的最佳实践是默认使用const,只在确定变量值需要改变的时候使用let。

已经看到有人翻译了这一章,戳这里阅读

Strings and Regular Expressions

用codePointAt来更好地unicode 支持

function is32Bit(c) {
    return c.codePointAt(0) > 0xFFFF;
}

console.log(is32Bit("?"));         // true
// 这个值可能显示不出来,可以用console.log(String.fromCodePoint(134071))来看


console.log(is32Bit("a"));          // false

16bit字符的上限在十六进制中用ffff来代表,因此,任何code point值大于这一数值的都是用两个code unit来代表的,是32位。

String类的normalize方法

在国际化的应用中尤为有用。在比较两个字符串时,应先采用同样的方式(nfc, nfd, nfkc, nfkd)将其标准化后,再进行比较。默认的标准化形式是nfc。
let values = [str1, str2] //自己定义两个字符串用于比较
values.sort(function(first, second) {
    var firstNormalized = first.normalize("NFD"),
        secondNormalized = second.normalize("NFD");

    if (firstNormalized < secondNormalized) {
        return -1;
    } else if (firstNormalized === secondNormalized) {
        return 0;
    } else {
        return 1;
    }
}); 

正则表达式中的 u 标志

在正则中加入u标志后,将以字符为基准而不是code单位(16位或32位)为基准来处理。
只要是一个字符的string, 不管是16位还是32位(看Length,不管是1还是2),都可以用

/^.$/u.test(str)

来校验。
那怎么获取字符串以字符为基准的length呢?可以这样做:

function codePointLength(text) {
    var result = text.match(/[\s\S]/gu);
    return result ? result.length : 0;
}
// 这么做的速度较慢,尤其是应用于长字符串时。应当尽量减少这么做的可能,考虑用字符串迭代器(iterator)来代替

other string changes

  • 子字符串

    1. includes()
    2. startsWith()
    3. endsWith()

    两个参数:搜索的字符串(不支持正则),和起始搜索下标(非必要,如果不传实质default为0)
    对 endsWith,是从字符串的长度减去第二个参数开始匹配

  • repeat() 方法

    'abc'.repeat(2)  //'abcabc'
    
    //应用在缩进级别中:
    
    var indent = ''.repeat(4),
        indentLevel = 0;
    
    var newIndet = indent.repeat(++indentLevel);
    

other regular expression changes

  • y flag
    对不加flag的正则表达式,pattern的lastIndex值无影响
    对有global flag的正则表达式,当pattern 的lastIndex 属性设置为某个值n时,正则表达式会从n开始全局匹配。
    对有y flag的正则表达式,其sticky属性会被设置为true,从lastIndex开始尝试匹配(但不是全局匹配)

    sticky flag会在正则表达式中保存最近一次匹配的后一位下标。如果没有任何匹配,lastIndex则会被设置为0.全局的’g’ flag 同理。

    y flag 和 u flag 都是新语法,可用try catch 包裹以防止报错。

复制正则表达式

var re1 = /ab/i,re2 = new RegExp(re1);

re1 === re2 //false

typeof re1 //"object"

es6 中,可以加入第二个参数flag符,用来覆盖掉原有的flags

var re1 = /ab/i,

    // throws an error in ES5, okay in ES6
re2 = new RegExp(re1, "g");

flags 属性

re 的 flags 属性可以提取flag

var re = /ab/g;

console.log(re.source);     // "ab"
console.log(re.flags);      // "g"

模板字符串

这个是重头戏了,挑一些平时不太注意的细节讲讲吧。

多行文字中要注意新行之前的空格也被计入字符串的一部分,如果需要缩进的话,可以在字符串后用上trim()方法

  • tagged templates
let count = 10,
    price = 0.25,
    message = passthru`${count} items cost $${(count * price).toFixed(2)}.`;

function passthru(literals,...substitutions){
    console.log(arguments);  //Arguments(3) [Array(3), 10, "2.50"] 展开array(3)是["", " items cost $", ".", raw: Array(3)]

    console.log('substitutions',substitutions);  //substitutions (2) [10, "2.50"]

    return literals.join('***')  
}

// message 的 值为 "*** items cost $***."

注意:
1. literals的length永远比substitutions的多一个
2. substitutions不一定是string,也可能是number

  • String.raw()

内置的String.raw() tag 可以避免字符转义,另外literals数组中也有raw属性,literals.raw是原字符串数组(未被转义)

let message1 = `Multiline\nstring`,
    message2 = String.raw`Multiline\nstring`;

console.log(message1);          // "Multiline
                                //  string"
console.log(message2);          // "Multiline\\nstring"

function raw(literals, ...substitutions) {
    let result = "";

    // run the loop only for the substitution count
    for (let i = 0; i < substitutions.length; i++) {
        result += literals.raw[i];      // use raw values instead
        result += substitutions[i];
    }

    // add the last literal
    result += literals.raw[literals.length - 1];

    return result;
}

let message = raw`Multiline\nstring`;

console.log(message);           // "Multiline\\nstring"
console.log(message.length);    // 17

summary

完备的unicode 支持让jaascript可以从逻辑上处理utf-16字符。code point 和 字符(character)之间可以通过 codePointAt() 和 String.fromCodePoint() 转换。新增的u字符让基于code points而不是基于16位字符处理成为可能。normalize()方法可以更适当地比较字符串。

includes, startsWith, endsWith 方法可以直接用true/false 来判断是否包含子字符串。

模板字符串可以方便地创建dsls(领域专用语言,domain-specific languages)。它支持变量代入和多行。template tags 尤其适用于创建dsls。