目录
文章目录
block bindings
原先的 var
var 声明的变量会被提升到函数的顶部,如果不在函数中的话,就等于提升到全局的顶部。等于把var a = 1拆分成2部分,var a 和 a = 1,前者被提升。
let/const
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。
const prevents modification of the binding, not modification of the bound value
Strings and Regular Expressions
用codePointAt来更好地unicode 支持
对超出了第一个2^16个代码点的Utf-16字符(即BMP,多语言基本面之外的字符),是不能用单个16位code unit表示的。对这些扩展字符集,会用2个code unit来表示。因此,用codePointAt()而不是charCodeAt()来按code unit的位置获取unicode 的 code point 值(就是一个整数),会更加准确,得到预期的结果
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 标志
正则表达式假定单个字符使用一个 16 位的码元来表示。在正则中加入u标志后,将以字符为基准而不是code单位(16位或32位)为基准来判断。u的含义是unicode。
只要是一个字符的string, 不管是16位还是32位(看Length,不管是1还是2),都可以用 /^.$/u.test(str)来校验。
var text = "𠮷";
console.log(text.length); // 2
console.log(/^.$/.test(text)); // false
console.log(/^.$/u.test(text)); // true
也可以轻松地利用/u来获取字符串以字符为基准的长度:
function codePointLength(text) {
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0;
}
// 这么做的速度较慢,尤其是应用于长字符串时。应当尽量减少这么做的可能,考虑用字符串迭代器(iterator)来代替
other string changes
-
子字符串 return true/false
- 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, which is short for sticky
/y表示从正则表达式的 lastIndex 属性值的位置开始检索字符串中的匹配字符。对不加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 $***."
注意:
- literals的length永远比substitutions的多一个
- 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。
本文深入探讨了ES6带来的变化,包括block bindings的新机制、增强的Unicode支持、字符串及正则表达式的改进等,同时介绍了模板字符串的实用技巧。
323

被折叠的 条评论
为什么被折叠?



