理解ES6 (1) var, let, const 之间的区别 (2) 字符串和正则表达式
目录
block bindings
es6中引进了let和const,需要注意的地方如下:
- block binding是指function或者{}。let 和 const 声明的变量不会提升,只在被声明之后才存在。在这之前变量处于时间死亡域中(tdz: temporal dead zone),甚至不能用貌似安全的操作符诸如typeof 来获取。
- let 和 const 在循环中与var不一样。for in 和 for of 都在每一次循环的iteration中生成了一个新的引用。因此,在循环体中生成的函数可以获取到当前迭代(interation)中的引用值,而不是循环之后的最终值。let在for循环中也是同理,但const不能用于for循环,因为改变了变量值。
- 用let或者const声明的变量,不能在该作用域下再次声明。let可以改变其值,const不能改变。const了就是常量了!
- 块级绑定的最佳实践是默认使用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
-
子字符串
- includes()
- startsWith()
- 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。
上一篇: Ajax 异步加载解析
下一篇: js关闭页面(兼容浏览器)