ES6是ECMA为JavaScript制定的第6个标准版本,标准委员会决定,标准在每年6月正式发布并作为当年的正式版本,接下来的时间里就在此版本的基础上进行改动,直到下一年6月草案就自然变成新一年的版本,这样一来就无需以前的版本号,只要用年份标记即可。ECMAscript 2015是在2015年6月发布ES6的第一个版本。以此类推,ECMAscript 2016是ES6的第二个版本、 ECMAscript 2017是ES6的第三个版本。
ES6既是一个历史名词也是一个泛指,含义是5.1版本以后的JavaScript下一代标准,目前涵盖了ES2015、ES2016、ES2017、ES2018、ES2019、ES2020。
所以很多文章提到的es7,es8等,实质上都是不规范的概念,从ES1到ES6,每个标准都是花了好几年甚至十多年才制定下来,你一个ES6到ES7,ES7到ES8,才用了一年,按照这样的定义下去,那不是很快就ES20了。用正确的概念来说ES6目前涵盖了ES2015、ES2016、ES2017、ES2018、ES2019、ES2020。
另外,ES6更新的内容主要分为以下几点
表达式:声明、解构赋值
内置对象:字符串扩展、数值扩展、对象扩展、数组扩展、函数扩展、正则扩展、Symbol、Set、Map、Proxy、Reflect
语句与运算:Class、Module、Iterator
异步编程:Promise、Generator、Async
注意
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
共享内存和原子操作:由全局对象SharedArrayBuffer和Atomics实现,将数据存储在一块共享内存空间中,这些数据可在JS主线程和web-worker线程之间共享
globalThis:作为顶层对象,指向全局环境下的this
Browser:顶层对象是window
Node:顶层对象是global
WebWorker:顶层对象是self
以上三者:通用顶层对象是globalThis
do表达式:封装块级作用域的操作,返回内部最后执行表达式的值(do{})
throw表达式:直接使用throw new Error(),无需()或{}包括
!#命令:指定脚本执行器(写在文件首行)
字符串解构:const [a, b, c, d, e] = "hello"
数值解构:const { toString: s } = 123
布尔解构:const { toString: b } = true
对象解构
const { x, y } = { x: 1, y: 2 }const { x, y = 2 } = { x: 1 }const { x, y: z } = { x: 1, y: 2 }数组解构
Iterator接口可采用数组形式的解构赋值const [x, y] = [1, 2]const [x, y = 2] = [1]函数参数解构
function Func([x = 0, y = 1]) {}function Func({ x = 0, y = 1 } = {}) {}应用场景
[x, y] = [y, x]const [x, y, z] = Func()Func([1, 2])const { name, version } = packageJsonfunction Func({ x = 1, y = 2 } = {}) {}for (let [k, v] of Map) {}const { readFile, writeFile } = require("fs")注意
undefinedundefinedundefined和null无法转为对象,因此无法进行解构let x;
{x} = {x: 1};
// SyntaxError: syntax error
这段代码会报错,因为JavaScript引擎会将{x}理解成一个代码块,从而发生语法错误。
只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题。
\u{0xXX}或\u{0XXX}),有了这种表示法之后,JavaScript 共有 6 种方法可以表示一个字符。‘\z‘ === ‘z‘ // true
‘\172‘ === ‘z‘ // true
‘\x7A‘ === ‘z‘ // true
‘\u007A‘ === ‘z‘ // true
‘\u{7A}‘ === ‘z‘ // true
for-of遍历字符串for (let codePoint of ‘foo‘) {
console.log(codePoint)
}
// "f"
// "o"
// "o"
//这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点。
let text = String.fromCodePoint(0x20BB7);
for (let i = 0; i < text.length; i++) {
console.log(text[i]);
}
// " "
// " "
for (let i of text) {
console.log(i);
}
// "??"
字符串模板:可单行可多行可插入变量的增强版字符串
标签模板:函数参数的特殊调用,需要注意的是:模板字符串中变量必须是由非变量包含着的,如果变量在开始位置或者结束位置且没有非变量包含,那么该位置就是空字符串。
var a = 5;
var b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
//等同于
tag([‘Hello ‘, ‘ world ‘, ‘‘], 15, 50);
let name = "Bob";
String.raw `Hi\n${name}!`;
// "Hi\nBob!",内插表达式还可以正常运行
String.fromCodePoint(42); // "*"
String.fromCodePoint(65, 90); // "AZ"
String.fromCodePoint(0x404); // "\u0404"
codePointAt():返回字符对应码点(String.fromCodePoint()的逆操作)
normalize():把字符的不同表示方法统一为同样形式,返回新字符串(Unicode正规化)
repeat():把字符串重复n次,返回新字符串
matchAll():返回正则表达式在字符串的所有匹配
includes():是否存在指定字符串
startsWith():是否存在字符串头部指定字符串
endsWith():是否存在字符串尾部指定字符串
const str = ‘123‘
str.padStart(str.length + 1, ‘a‘) // => ‘a123‘
UTF-8标准的字符串0bXX或0BXX)0oXX或0OXX)-2^53)2^53)NaNe^n - 11 + n的自然对数(Math.log(1 + n))Math.pow())BigInt类型BigInt为0到2n-1之间对应的值BigInt为-2n-1到2n-1-1Number.parseInt(),将一个字符串转换成指定进制的BigInt类型let budget = 1_000_000_000_000;
budget === 10 ** 12 // true
{ prop, method() {} })[prop],不能与上同时使用)enumerablemethod() {})getter)和存值函数(setter):get/set函数名(属性的描述对象在get和set上)bound函数名anonymous{ ...obj },相当于rest/spread参数的逆运算)Object.entries()的逆操作)undefined且不再往下执行)
obj?.prop、obj?.[expr]func?.(...args)undefined或null,是则使用默认值[...arr],相当于rest/spread参数的逆运算)Iterator接口的数据结构为真正数组,返回新数组
length的对象、Arguments对象、NodeList对象String、Set结构、Map结构、Generator函数undefined(空位处理规不一,建议避免出现)function Func(x = 1, y = 2) {}
rest/spread参数(...):返回函数多余参数,以数组的形式存在,之后不能再有其他参数
严格模式:在严格条件下运行JS,如果函数参数使用默认值、解构赋值、扩展运算符,那么函数内部就不能显式设定为严格模式
箭头函数(=>):函数简写
尾调用优化:只保留内层函数的调用帧,不会发生栈溢出,相对节省内存
function f(x) { return g(x); }
catch()中的参数可省略let obj = {
f(x, y) { return x + y; },
};
const g = obj.f(?, 3);
g(1) // 4
f(x) => x |> f)bind、apply、call调用)
bar.bind(foo) => foo::barbar.apply(foo, arguments) => foo::bar(...arguments)match()、replace()、search()、split()内部调用转为调用RegExp实例对应的RegExp.prototype[Symbol.方法]Unicode模式修饰符,正确处理大于\uFFFF的Unicode字符g修饰符作用类似)u修饰符y修饰符dotAll模式修饰符,使.匹配任意单个字符(dotAll模式)s修饰符x只有在y后才匹配x只有不在y后才匹配Unicode某种属性的所有字符
\p{PropRule}\P{PropRule}\p{...}和\P{...}只对Unicode字符有效,使用时需加上u修饰符?<GroupName>)独一无二的值, symbol
类似于数组的数据结构,成员值都是唯一且没有重复的值, set
类似于对象的数据结构,成员键是任何类型的值, map
修改某些操作的默认行为,proxy
const proxy = new Proxy(target, handler)
保持Object方法的默认行为。reflect
设计目的
对一类具有共同特征的事物的抽象(实质是基于原型的继承的语法糖), class
export default Person
import Person from "person"
export命令和import命令结合在一起写成一行,变量实质没有被导入当前模块,相当于对外转发接口,导致当前模块无法直接使用其导入变量export { default } from "person"
其他模块方案
//CommonJS
// a.js
module.exports = {
a: 1
}
// or
exports.a = 1
// b.js
var module = require(‘./a.js‘)
module.a // -> log 1
// AMD
define([‘./a‘, ‘./b‘], function(a, b) {
// 加载模块完毕可以使用
a.do()
b.do()
})
// CMD
define(function(require, exports, module) {
// 加载模块
// 可以把 require 写在函数体的任意地方实现延迟加载
var a = require(‘./a‘)
a.doSomething()
})
//UMD
(function (root, factory) {
if (typeof define === ‘function‘ && define.amd) {
//AMD
define([‘jquery‘], factory);
} else if (typeof exports === ‘object‘) {
//Node, CommonJS之类的
module.exports = factory(require(‘jquery‘));
} else {
//浏览器全局变量(root 即 window)
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
//方法
function myFunc(){};
//暴露公共方法
return myFunc;
}));
为各种不同的数据结构提供统一的访问机制, 主要使用for-of进行遍历, iterator
包含异步操作结果的对象, promise
封装多个内部状态的异步编程解决方案
function Wrapper(func) {
return function(...args) {
const generator = func(...args);
generator.next();
return generator;
}
}
const print = Wrapper(function*() {
console.log(`First Input: ${yield}`);
return "done";
});
print().next("hello");
注意
next(),指针就从函数头部或上次停下的位置开始执行,直到遇到下一个yield命令或return语句为止yield命令,但会变成单纯的暂缓执行函数(还是需要next()触发)yield命令是暂停执行的标记,next()是恢复执行的操作yield命令用在另一个表达式中必须放在圆括号里yield命令用作函数参数或放在赋值表达式的右边,可不加圆括号yield命令本身没有返回值,可认为是返回undefinedyield命令表达式为惰性求值,等next()执行到此才求值Symbol.iterator是此对象本身next()从外部向内部注入不同的值,从而调整函数行为next()用来启动遍历器对象,后续才可传递参数next()时就能输入值,可在函数外面再包一层next()返回对象的done为true,for-of遍历会中止且不包含该返回对象try-finally且正在执行try,那么return()会导致立刻进入finally,执行完finally以后整个函数才会结束throw()抛错要被内部捕获,前提是必须至少执行过一次next()throw()被捕获以后,会附带执行下一条yield命令throw()抛错只可能抛出在函数外部提供沙箱功能,允许隔离代码,防止被隔离的代码拿到全局对象
new Realm().global



原文:https://www.cnblogs.com/wangxi01/p/12757767.html