ECMAScript 6+标准学习

ECMAScript 6+学习笔记

ES6 的第一个版本,就这样在 2015 年 6 月发布了,正式名称就是《ECMAScript 2015 标准》(简称 ES2015)。2016 年 6 月,小幅修订的《ECMAScript 2016 标准》(简称 ES2016)如期发布,这个版本可以看作是 ES6.1 版,因为两者的差异非常小,基本上是同一个标准。根据计划,2017 年 6 月发布 ES2017 标准。

因此,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。

Update Time:

根据我的理解将内容分为两个大的部分:新增扩展

新增内容

[1] Let and Const Declarations

let仅在当作用范围有效,且无如var的变量提升:在 JavaScript 中,var声明的变量在赋值之前就已经存在,其值为undefined

let不允许重复声明。

let新增了块级作用域。能够防止内层变量覆盖全局变量,防止内层变量泄露到全局变量。

const声明一个只读、不变的“常量”,实际上固定了一个变量的内存地址。当const声明对象数组时,其指向的地址不变,当指向对象的值是可变的。

1
2
3
4
5
6
7
8
const arr = [];
const obj = {};
arr.push(1);
console.log(arr);
// -> [1]
obj.name = "obj";
console.log(obj.name);
// -> 'obj'

[2] String 的新增方法

  • String.fromCodePoint(/*unicode*/) 用于返回 Unicode
  • String.raw(/*string*/) 用于返回原始字符串,即将字符串转义后显示
  • String.prototype.codePointAt(/*index*/) 解析字符串中的 Unicode 码
  • String.prototype.normalize(/*arg*/) 用于合成多字节 Unicode 字
  • String.prototype.includes(/*toFind*/) 返回是否包含参数字符串
  • String.prototype.startsWith(/*toFind*/) 返回字符串头部是否是参数字符串
  • String.prototype.endsWit(/*toFind*/) 返回字符串尾部是否是参数字符串
  • String.prototype.repeat(/*uint n*/) 将字符串重复 n 次
  • String.prototype.padStart(/*uint len, string*/) 使用第二个参数在起始补全第一个参数值的长度
  • String.prototype.padEnd(/*uint len, string*/) 使用第二个参数在末尾补全第一个参数值的长度
  • String.prototype.trimStart() 消除起始空格,不修改原字符串
  • String.prototype.trimEnd() 消除末尾空格,不修改原字符串
  • String.prototype.matchAll() 返回正则所有匹配
  • String.prototype.replaceAll(/*old, new*/) 全部替换匹配值
  • String.prototype.at(/*index*/) 返回指定位置的字符

[3] RegExp

新增修饰符u: Unicode 模式,能够正常识别双字符 Unicode 字,同时.能够正常匹配所有 Unicode 字符

新增RegExp.prototype.unicode检查是否有u修饰符

新增修饰符y: 从上一个匹配到的位置开始匹配

新增RegExp.prototype.sticky检查是否有y修饰符

新增RegExp.prototype.flags显示所有修饰符

新增修饰符s: dotAll,使得.修饰所有字符

新增后行断言:lookbehind:

1
2
3
4
// 已有先行断言
/\d+(?=%)/ /* 表示匹配%前方的数字 */
// 新增后行断言
/(?<=#)\d+/ /* 表示匹配#之后的数字 */

新增命名组匹配(类似 Python 中),可以进行后续引用。

1
2
3
4
5
6
const reDate = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchRes = reDate.exec("2022-01-01");
const { year, month, day } = matchRes.groups;
const reTwice = /^(?<word>\w+)-\k<word>$/;
reTwice.test("abc-abc");
// -> true

[4] Number

新增二进制0b0100八进制0o4。转换:Number('0b0100') = 4

新增数值分隔符1000 == 1_000

新增Number.isFinite(/*number*/) 判断是否为有限数值

新增Number.isNaN(/*number*/) 判断是否为NaN类型

新增Number.isInteger() 判断是否为整数。特别地,JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值;如果数值的精度超过这个限度,第 54 位及后面的位就会被丢弃,这种情况下,Number.isInteger可能会误判;如果一个数值的绝对值小于Number.MIN_VALUE(5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0,这时,Number.isInteger也会误判

新增Number.EPSILON代表一个极小的常量Number.EPSILON === Math.pow(2, -52)

新增Number.isSafeInteger(),同时新增最大、最小整数常量Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER

[5] Math

  • Math.trunc(/*number*/) 去除小数部分,返回整数部分;首先转换为数值,若无法转换,返回NaN

  • Math.sign(/*number*/) 判断参数正负,返回值:+1 -1 0 -0 NaN

  • Math.cbrt(/*number*/) 计算立方根

  • Math.clz32(/*number*/) 将参数转为 32 位无符号整数的形式,然后返回这个 32 位值里面有多少个前导 0

  • Math.imul(/*numbers*/) 返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数

    1
    2
    3
    4
    (0x7fffffff * 0x7fffffff) | 0;
    // -> 0
    Math.imul(0x7fffffff, 0x7fffffff);
    // -> 1
  • Math.fround(/*number*/) 返回一个数的 32 位单精度浮点数形式

  • Math.hypot(/*numbers*/) 返回所有参数的平方和的开方

  • Math.expm1(/*number*/) 返回$e^x-1$,等价于Math.exp(x) - 1

  • Math.log1p(/*number*/) 返回$\ln(1 + x)$

  • Math.log10(/*number*/) 返回$\lg x$

  • Math.log2(/*number*/) 返回$\log_2 x$

  • Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)

  • Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)

  • Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)

  • Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)

  • Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)

  • Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

[6] BigInt

用来表示整数,没有位数限制。需要添加后缀n

1
2
3
let n = 7378697629483821n;
typeof n;
// -> 'bigint'

也可以进行转换

1
BigInt("123"); // -> 123n

实例方法:

1
2
3
BigInt.prototype.toString();
BigInt.prototype.valueOf();
BigInt.prototype.toLocaleString();

静态方法:

  • BigInt.asUintN(width, BigInt): 给定的 BigInt 转为 0 到 2width - 1 之间对应的值。
  • BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2width - 1 到 2width - 1 - 1 之间对应的值。
  • BigInt.parseInt(string[, radix]):近似于Number.parseInt(),将一个字符串转换成指定进制的 BigInt。

扩展内容

(1) globalThis

globalThis是全局对象(The global object)的扩展,其属性如下:

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.

(2) Destructuring Assignment

变量的解构语法能够方便地解构数组(array)、对象(object)内部的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// LeftHandSideExpression = AssignmentExpression
let a = 1,
b = 2;
[a, b] = [b, a];
console.log(a, b);
// -> 2 1
const obj = {
name: "obj",
getter() {
return this.name;
},
};
// 将变量扩充到window全局对象中
var { name, getter } = obj;
console.log(name);
// -> 'obj'
// getter中的this->window
getter();
// -> 'obj'

同样可以多层解构和部分解构,只要与被解构的结构相同即可。

由于 JavaScript 内部皆对象,则对象的解构可以用于能够被转换为对象的:数组、字符串、数值、布尔值。

(3) Unicode

单字节 Unicode: "\u0061",双字节 Unicode: "\u{20BB7}"

(4) Template strings

字符串的扩展声明语法,使用反引号表示`,内部可插入表达式。可以包含多行字符串。

1
2
3
let resp = { status: 0 };
let text = `response: ${resp.status == 0 ? "ok" : "error"}`;
console.log(text);

可以作为第一个参数传入函数:

1
2
3
4
5
function add(arg) {
return ++parseInt(arg);
}
console.log(add`12`);
// -> 13

但是如果包含模版内表达式,则会换转为多个参数。将表达式切分为多个部分,传递给参数 0,然后将表达式结果依次传递给后续参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let a = 1,
b = 2;
add`${a + b}`; // 错误!Uncaught ReferenceError: Invalid left-hand side expression in prefix operation
function tag(arg, ...args) {
console.log(arg);
if (args) {
for (const i of args) {
console.log(i);
}
}
}
tag`part1${a + b}part2${a * b}part3`;
// -> ['part1', 'part2', 'part3']
// -> 3
// -> 2

(5) Function

可为参数添加默认值function(n = 0) {} 当传入参数为undefined时触发,需要放在尾部

将默认值设定为undefined代表是可以省略的

Function.prototype.length返回需要传入参数的个数

新增rest参数function(...rest) {}包含传递参数的数组,必须放在尾部

Function.prototype.name返回函数名,或者匿名函数的变量名

箭头函数() => {}用于快速编写匿名函数,其不包含自己的作用域。将this固定化,有利于封装回调函数

变化内容

<1> RegExp Constructor

RegExp构造函数可以同时接收正则表达式和修饰符参数。参数会覆盖表达式中的修饰符。

1
2
new RegExp(/abc/gi, "i").flags;
// -> 'i'

<2> RegExp property

ES6 将这 4 个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上。

  • String.prototype.match 调用 RegExp.prototype[Symbol.match]
  • String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
  • String.prototype.search 调用 RegExp.prototype[Symbol.search]
  • String.prototype.split 调用 RegExp.prototype[Symbol.split]

<3> Number

parseInt() parseFloat()移动到Number对象中

打赏
  • 版权声明: 本博客采用 Apache License 2.0 许可协议。
    转载请注明出处: https://ryzenx.com/2022/01/JS-ES6/

谢谢你的喜欢~

支付宝
微信