@JunQiu
2018-09-18T18:21:50.000000Z
字数 3076
阅读 1142
summary_2018/07
pocc(计组)
language_node
字符的unicode表示法
JavaScript 允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。(但只限于\u0000~\uFFFF之间的字符(单字节),超出这个范围需要用双字节表示)
Example:
\u0061 : a
超出单字节:\u00617 : a7 (即\u0061+7)
双字节:"\uD842\uDFB7" :𠮷
# es6引入新的改变,可以同时理解双字节和单字节:
"\u{20BB7}" :𠮷
Tips:JavaScript 内部,字符以 UTF-16(0000 0000 0010 0100) 的格式储存,每个字符固定为2个字节。对于那些需要4个字节储存的字符(Unicode 码点大于0xFFFF的字符),JavaScript 会认为它们是两个字符。
var s = "𠮷";
s.length // 会当作两个字符
s.charAt(0) // ''无法读取
s.charAt(1) // ''
s.charCodeAt(0) // 55362 返回前两个字节
s.charCodeAt(1) // 57271
汉字“𠮷”(注意,这个字不是“吉祥”的“吉”)的码点是0x20BB7,UTF-16 编码为0xD842 0xDFB7(十进制为55362 57271)
# es6 提供codePointAt方法。能够正确处理4个字节存储的字符
let s = '𠮷a';
s.codePointAt(0) // 134071
s.codePointAt(1) // 57271
s.codePointAt(2) // 97
JavaScript 将“𠮷a”视为三个字符,codePointAt 方法在第一个字符上,正确地识别了“𠮷”,返回了它的十进制码点 134071(即十六进制的20BB7)。在第二个字符(即“𠮷”的后两个字节)和第三个字符“a”上,codePointAt方法的结果与charCodeAt方法相同。(但实际上,在上面a的位置是不对的,可以用for..of解决)
# ES5 提供String.fromCharCode方法,用于从码点返回对应字符,但是这个方法不能识别 32 位的 UTF-16 字符(Unicode 编号大于0xFFFF)。ES6 提供了String.fromCodePoint方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode方法的不足。
# es6提供字符遍历接口
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
Tips:字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果。用数组的方式遍历中文字符,大于两个字节的情况会出现错误,可以用for...of解决
# ES5 对字符串对象提供charAt方法,返回字符串给定位置的字符。该方法不能识别码点大于0xFFFF的字符。目前有一个提案,用at解决
# 传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。es6提供三种新方法:
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
# es6模板字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量/表达式/函数。
`Hello ${name}, how are you ${time}?`
标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。
alert`123`
// 等同于
alert(123)
Tips:如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);
函数tag依次会接收到多个参数。
function tag(stringArr, value1, value2){
// ...
}
// 等同于
function tag(stringArr, ...values){
// ...
}
tag函数的第一个参数是一个数组,该数组的成员是模板字符串中那些没有变量替换的部分,也就是说,变量替换只发生在数组的第一个成员与第二个成员之间、第二个成员与第三个成员之间,以此类推。
tag函数的其他参数,都是模板字符串各个变量被替换后的值。由于本例中,模板字符串含有两个变量,因此tag会接受到value1和value2两个参数。
# ES6 还为原生的 String 对象,提供了一个raw方法。
String.raw方法,往往用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字符串。
# 二进制和八进制表示法。ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。
# Number.isFinite(), Number.isNaN()
ES6 在Number对象上,新提供了Number.isFinite()(是否有限)和Number.isNaN()两个方法。
Tips:传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
# ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变
# Number.isInteger()用来判断一个数值是否为整数。在js内部整数和浮点数用同样的方式存储,因此25和25.0是同一个值,且如果参数不是数值,Number.isInteger返回false。
# ES6 在Number对象上面,新增一个极小的常量Number.EPSILON。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。(Number.EPSILON实际上是 JavaScript 能够表示的最小精度。)
# 安全整数和 Number.isSafeInteger()
JavaScript 能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个值。
# 在Math对象上增加了17个方法
# ES2016 新增了一个指数运算符(**)。
2 ** 2 // 4
2 ** 3 // 8