(走运时,要想到倒霉,不要得意得过了头;倒霉时,要想到走运,不必垂头丧气。心态始终保持平衡,情绪始终保持稳定,此亦长寿之道。。——季羡林)
ECMA
ecma官方网站
ecma github版本记录
w3schools
ECMAScript是由网景的布兰登·艾奇开发的一种脚本语言的标准化规范;最初命名为Mocha,后来改名为LiveScript,最后重命名为JavaScript。1995年12月,升阳与网景联合发表了JavaScript。1996年11月,网景公司将JavaScript提交给欧洲计算机制造商协会进行标准化。ECMA-262的第一个版本于1997年6月被Ecma组织采纳。ECMA Script是ECMA-262标准化的脚本语言的名称。尽管JavaScript和JScript与ECMAScript兼容,但包含超出ECMA Script的功能。
ecma从2016年开始以年份命名,旧的es版本以数字命名,比如ES5 (2009) 和 ES6 (2015)
但依然也可以用数字命名
| 版本 | 年份 |
|---|---|
| ES2009 Or ES5 | June 2009 |
| ES2015 Or ES6 | June 2015 |
| ES2016 Or ES7 | June 2016 |
| ES2017 Or ES8 | June 2017 |
| ES2018 Or ES9 | June 2018 |
| ES2019 Or ES10 | June 2019 |
| ES2020 Or ES11 | June 2020 |
| ES2021 Or ES12 | June 2021 |
| ES2022 Or ES13 | June 2022 |
接下来整理的是开发中常用的特性,一些作者认为不常用的可能会不记录或者记录的不详细
ES13
2022 年 6 月发布
1. await和async解除强绑定
await不再必须写在async里了,在过去,我们通常的写法如下。
import posts from './posts'; const getPosts = async() => {
let posts = await posts(); return posts; }
讯享网
在es13中,我们可以直接这样。
讯享网let posts = await posts();
解除和async的强绑定有以下好处
- 动态依赖路径
当你有依赖运行时值的动态路径时,await 有助于在运行时加载或导入消息。
const messages = await import(`./messages-${
language}.js`);
- 依赖回退
如果导入的模块加载失败,则加载的回退模块用于加载依赖。
讯享网let lodash; try {
lodash = await import('https://first.domain.com/lodash'); } catch {
lodash = await import('https://second.domain.com/lodash'); }
- 资源初始化
此功能可用于使用数据库初始化应用程序。
import {
dbConnector} from './dbUtils.js' //connect to database const connection = await dbConnector.connect(); export default function(){
connection.list() }
- 本身不作为promise类型返回,但内部业务代码处理需要使用await的
2. 支持私有属性和方法
在过去,我们编写类的私有属性和方法时常借助typescript的private来实现,但使用js的话因为没有严格限制,所以需要特殊命名来进行标记,比如在变量命名前加下划线_。但因为不强制进行检查,可能会导致业务错误。
讯享网 class Employee {
constructor() {
this.name = "John"; //public this._age=35; //private } const employee = new Employee(); employee.name = "Jack"; employee._age =35; //No error
现在,es13原生支持了公开和私有的属性方法,提高了js代码的扩展性和可维护性。
通过在变量前添加#号,标记其为私有属性或方法。
在下面的示例中,Employee 类已在构造函数外部使用私有变量定义。
class Employee {
name = "John"; #age=35; constructor() {
} #getAge() {
return #age } } const employee = new Employee(); employee.name = "Jack"; employee.#age = 35; // Throws an error
并且还支持静态字段和方法。只需要在前面加入static标记即可。
讯享网class Employee{
name = "John"; static #employerName="Github" static #getEmployerName() {
return #employerName } } const employee = new Employee(); employee.emp = "Jack"; employee.#employerName = 35; // Throws an error
3. 数组at()方法
const array = [1, 2, 3, 4, 5]; console.log(array[array.length - 2]); //4 console.log(array.slice(-2)[0]); //4 const string = '12345'; console.log(string[string.length - 2]); // '4' console.log(string.slice(-2)[0]); // '4'
现在你应该可以写。
讯享网const array = [1, 2, 3, 4, 5]; console.log(array.at(-2)); // 4 const string = '12345'; console.log(string.at(-2));
4. 自定义错误原因
在下面的示例中,让我们从 JSON 处理中捕获错误,并使用一条新的有意义的消息以及错误的原始原因重新抛出它。
function processUserData(arrayData) {
return arrayData.map(data => {
try {
const json = JSON.parse(data); return json; } catch (err) {
throw new Error( `Data processing failed`, {
cause: err} ); } }); }
5. Object.hasOwn()
新的Object.hasOwn()方法替代了Object.prototype.hasOwnProperty。它是一个静态方法,比hasOwnProperty写法更简洁,并解决了hasOwnProperty的一些问题。
讯享网const user = Object.create(null); user.age = 35; user.hasOwnProperty('age'); // throws a TypeError
在这种情况下,可以使用 hasOwn() 方法来确定自己的属性。
const user = Object.create(null); user.age = 35; user.hasOwn('age'); // true
6. 正则表达式匹配索引
正则表达式匹配已升级为包含有关匹配组的更多信息。\d附加信息包括在输入字符串中使用标志的 RegExp 中匹配项的开始和结束索引。
ES12
2021年中发布
1. replaceAll()
讯享网 console.log(''.replace(new RegExp('0', 'g'), '1')); // console.log('0'.replace(/0/g, '1')); //
ES2021之后
console.log(''.replaceAll('0', '1')); // console.log('0'.replaceAll('0', '1')); //
2. promise.any
被传入的promise数组,先成功的将被作为返回值处理。如果全部失败则抛出异常。
讯享网let promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'Resolves after 100ms')); let promise2 = new Promise((resolve) => setTimeout(resolve, 200, 'Resolves after 200ms')); let promise3 = new Promise((resolve, reject) => setTimeout(reject, 0) ); let promises = [promise1, promise2, promise3]; Promise.any(promises) .then( value => console.log(value)); // Resolves after 100ms
(async () => {
try {
const output = await Promise.any([ Promise.reject('Error 1'), Promise.reject('Error 2'), Promise.reject('Error 3'), ]); console.log(`Output: ${
output}`); } catch (err) {
console.log(`Error: ${
err.errors}`); } })(); // Error: Error1,Error2,Error3
3. 弱引用
WeakRef 提供了两个新功能
- 使用 WeakRef 类创建对对象的弱引用
- 在对象被垃圾收集后运行用户定义的终结器,使用 FinalizationRegistry 类
在 ES12 之前,WeakMaps 和 WeakSets 是在 JavaScript 中弱引用对象的唯一方法。而 ES12 中的 WeakRef 提供了实际的弱引用,为对象的生命周期打开了一个窗口。
讯享网const myObject = new WeakRef({
name: ‘Sudheer’, age: 34 }); console.log(myObject.deref()); //output: {name: “Sudheer”, age: 35} console.log(myObject.deref().name); //output: Sudheer
对象FinalizationRegistry允许您在对象被垃圾回收时请求回调。它用作清理回调。
// Create new FinalizationRegistry: const reg = new FinalizationRegistry((val) => {
console.log(val); }); (() => {
// Create new object: const obj = {
} // Register finalizer for the "obj" as first argument and value for callback function as second argument: reg.register(obj, 'obj has been garbage-collected.') })();
4. 数字分隔符
数字分隔符通过使用下划线 (_) 在数字之间提供分隔,有助于在 JavaScript 中读取大数字(或数字文字)。换句话说,通过在数字组之间创建视觉分隔,数字文字更具可读性。
5. 逻辑运算符
讯享网 x = x && (x = y); (OR) if (x) {
x = y; }
在es12可以优化为
let x = 10; let y = 20; x &&= y; console.log(x); // 20
||=:比如以下代码
讯享网 x = x || (x = y); (OR) if (!x) {
x = y; }
可以优化为
let x = 0; let y = 20; x ||= y; console.log(x); // 20
??=:比如以下代码。
讯享网 x ?? (x = y); (OR) if (!x) {
x = y; }
可以优化为
let x; let y = 1; x ??= y; console.log(x); // 1
ES11
2020 年 6 月
1. 大整数
BigInt作为第 7 种原始类型引入,以表示大于 pow(2, 53) - 1(或 40991 或 Number.MAX_SAFE_INTEGER)的整数(具有任意精度的整数)。
讯享网// 1. Current number system const max = Number.MAX_SAFE_INTEGER; console.log(max + 1) // 40992 console.log(max + 2) // 40992 // 2. BigInt representation const bigInt = 40991n; const bigIntConstructorRep = BigInt(40991); // 40991n const bigIntStringRep = BigInt("40991"); // 40991n // 3. Typeof usage console.log(typeof 1)// number console.log(typeof 1n)// bigint console.log(typeof BigInt('1'))// bigint // 4. Operators const previousMaxNum = BigInt(Number.MAX_SAFE_INTEGER); console.log(previousMaxNum + 2n); //40993n (this was not possible before) console.log(previousMaxNum -2n); //40990n console.log(previousMaxNum * 2n); //n console.log(previousMaxNum % 2n); //1n console.log(previousMaxNum / 2n); // 70495n // 5. comparison console.log(1n === 1); // false console.log(1n === BigInt(1)); // true console.log(1n == 1); // true
2. 动态导入
引入新功能dynamic import是为了有条件地或按需加载模块。由于它返回请求模块的模块命名空间对象的承诺,因此可以解析模块或现在可以使用 async/await 将导入分配给变量,如下所示
<script> const moduleSpecifier = './message.js'; import(moduleSpecifier) .then((module) => {
module.default(); // Hello, default export module.sayGoodBye(); //Bye, named export }) .catch(err => console.log('loading error')); </script>
讯享网<script> (async function() {
const moduleSpecifier = './message.js'; const messageModule = await import(moduleSpecifier); messageModule.default(); // Hello, default export messageModule.sayGoodBye(); //Bye, named export })(); </script>
并且导入的模块出现默认和命名导出
export default () => {
return "Hello, default export"; } export const sayGoodBye = () => {
return "Bye, named export" }
注意:动态导入不需要脚本type=“module”
3. 无效合并运算符
讯享网let vehicle = {
car: {
name: "", speed: 0 } }; console.log(vehicle.car.name || "Unknown"); // Unknown console.log(vehicle.car.speed || 90); // 90 console.log(vehicle.car.name ?? "Unknown"); // ""(empty is valid case for name) console.log(vehicle.car.speed ?? 90); // 0(zero is valid case for speed)
简而言之,空值运算符返回一个非空值和 || 运算符返回真值。
4. 字符串全匹配
有一种String#match方法可以通过迭代每个匹配项来获取字符串与正则表达式的所有匹配项。但是,此方法会为您提供匹配的子字符串。
这String#matchAll()是一个添加到 String 原型的新方法,它返回一个字符串与正则表达式匹配的所有结果的迭代器。
const regex = /t(e)(st(\d?))/g; const string = 'test1test2'; const matchesIterator = string.matchAll(regex); Array.from(matchesIterator, result => console.log(result));
当您在浏览器控制台中编写此代码时,匹配迭代器会为每个匹配项生成一个数组,包括带有一些额外内容的捕获组。
讯享网["test1", "e", "st1", "1", index: 0, input: "test1test2", groups: undefined] ["test2", "e", "st2", "2", index: 5, input: "test1test2", groups: undefined]
5. 可选链接
let vehicle = {
}; let vehicle1 = {
car: {
name: 'ABC', speed: 90 } }; console.log(vehicle.car.name); // TypeError: Cannot read property 'name' of undefined console.log(vehicle.car?.name); // Undefined console.log(vehicle.car?.speed); // Undefined console.log(vehicle1.car?.name); // ABC console.log(vehicle1.car?.speed); // 90 console.log(vehicle.car?.name ?? "Unknown"); // Unknown console.log(vehicle.car?.speed ?? 90); // 90
6. allSettled
讯享网const promise1 = new Promise((resolve, reject) => setTimeout(() => resolve(100), 1000)); const promise2 = new Promise((resolve, reject) => setTimeout(reject, 1000)); Promise.allSettled([promise1, promise2]).then(data => console.log(data)); // [ // Object { status: "fulfilled", value: 100}, // Object { status: "rejected", reason: undefined} // ]
7. globalThis
在 ES2020 之前,你需要在不同的 JavaScript 环境(跨平台)中编写不同的语法来访问全局对象。window, self, or frames这对开发者来说真的是一段艰难的时期,因为你需要在浏览器端、globalnodejs 端、selfweb workers 端使用。
另一方面,this关键字可以在非严格模式的函数内部使用,但它在严格模式下给出 undefined 。如果您考虑将其Function(‘return this’)()作为上述环境的解决方案,那么对于启用 CSP 的环境(禁用 eval()),它将失败。
在旧版本中,你可以像下面这样使用 es6-shim,
var getGlobal = function () {
if (typeof self !== 'undefined') {
return self; } if (typeof window !== 'undefined') {
return window; } if (typeof global !== 'undefined') {
return global; } throw new Error('unable to locate global object'); }; var globals = getGlobal(); if (typeof globals.setTimeout !== 'function') {
console.log('no setTimeout in this environment or runtime'); }
在 ES2020 中,globalThis引入了属性以提供一种跨环境访问全局 this 值的标准方法。
讯享网if (typeof globalThis.setTimeout !== 'function') {
console.log('no setTimeout in this environment or runtime'); }
8. import.meta
9. for…in order
在 ES2020 之前,规范没有指定 (a in b) 的运行顺序。尽管大多数 javascript 引擎/浏览器按照对象的定义顺序循环访问对象的属性,但并非所有情况都是如此。这在 ES2020 中已经被正式标准化。
var object = {
'a': 2, 'b': 3, 'c': 4 } for(let key in object) {
console.log(key); // a b c }
ES10
2019 年 6 月
1. Array flat 和 flatMap
在 ES2019 之前,你需要使用reduce() or concat()方法来获取平面数组。
讯享网function flatten(arr) {
const flat = [].concat(...arr); return flat.some(Array.isArray) ? flatten(flat) : flat; } flatten([ [1, 2, 3], ['one', 'two', 'three', [22, 33] ], ['a', 'b', 'c'] ]);
在 ES2019 中,flat()引入了将嵌套数组“扁平化”为顶级数组的方法。该方法的功能类似于 Lodash 的_.flattenDepth()功能。此方法接受一个可选参数,该参数指定嵌套数组应展平的级别数,默认嵌套级别为 1。 注意:如果数组中有任何空槽,它们将被丢弃。
const numberArray = [[1, 2], [[3], 4], [5, 6]]; const charArray = ['a', , 'b', , , ['c', 'd'], 'e']; const flattenedArrOneLevel = numberArray.flat(1); const flattenedArrTwoLevel = numberArray.flat(2); const flattenedCharArrOneLevel = charArray.flat(1); console.log(flattenedArrOneLevel); // [1, 2, [3], 4, 5, 6] console.log(flattenedArrTwoLevel); // [1, 2, 3, 4, 5, 6] console.log(flattenedCharArrOneLevel); // ['a', 'b', 'c', 'd', 'e']
而flatMap()方法将map()and组合flat()成一个方法。它首先使用给定函数的返回值创建一个新数组,然后连接该数组的所有子数组元素。
讯享网const numberArray1 = [[1], [2], [3], [4], [5]]; console.log(numberArray1.flatMap(value => [value * 10])); // [10, 20, 30, 40, 50]
2. Object.fromEntries()
const obj = {
'a': '1', 'b': '2', 'c': '3' }; const arr = Object.entries(obj); console.log(arr); // [ ['a', '1'], ['b', '2'], ['c', '3'] ]
但是如果你想从数组中取回对象,那么你需要迭代并转换它,如下所示
讯享网const arr = [ ['a', '1'], ['b', '2'], ['c', '3'] ]; let obj = {
} for (let [key, val] of arr) {
obj[key] = val; } console.log(obj);
const arr = [ ['a', '1'], ['b', '2'], ['c', '3'] ]; const obj = Object.fromEntries(arr); console.log(obj); // { a: "1", b: "2", c: "3" }
使用此方法的一种常见情况是使用 URL 的查询参数
讯享网 const paramsString = 'param1=foo¶m2=baz'; const searchParams = new URLSearchParams(paramsString); Object.fromEntries(searchParams); // => {param1: "foo", param2: "baz"}
3. trimStart和trimEnd
//Prior ES2019 let messageOne = " Hello World!! "; console.log(messageOne.trimLeft()); //Hello World!! console.log(messageOne.trimRight()); // Hello World!! //With ES2019 let messageTwo = " Hello World!! "; console.log(messageTwo.trimStart()); //Hello World!! console.log(messageTwo.trimEnd()); // Hello World!!
4. Symbol description
在创建符号时,您还可以为其添加描述以用于调试目的。但是在ES2019之前没有直接访问描述的方法。考虑到这一点,ES2019 引入了一个只读描述属性来检索包含符号描述的字符串。
这使得访问符号对象的不同变体的符号描述成为可能
讯享网console.log(Symbol('one').description); // one console.log(Symbol.for('one').description); // "one" console.log(Symbol('').description); // '' console.log(Symbol().description); // unefined console.log(Symbol.iterator.description); // "Symbol.iterator"
5. 可选的捕获绑定
在 ES9 之前,如果您不需要error变量并省略相同的变量,则不会调用 catch() 子句。此外,linters 抱怨未使用的变量。为了避免这个问题,引入了可选的catch绑定特性,使catch子句中的绑定参数成为可选的。如果您想完全忽略该错误,或者您已经知道该错误但您只想对此做出反应,则此功能将很有用。
让我们看看以下版本之间的语法差异
// With binding parameter(<ES9) try {
··· } catch (error) {
··· } // Without binding parameter(ES9) try {
··· } catch {
··· }
6. JSON 改进
7. 数组稳定排序
8. function.toString()
函数有一个调用的实例方法toString(),它返回一个字符串来表示函数代码。以前版本的 ECMAScript 从函数代码中删除了空格、换行和注释,但它在 ES2020 中保留了原始源代码。
9. 私有类变量
在 ES6 中,引入了类来创建可重用的模块,并在 clousure 中声明了变量以使其私有化。而在 ES2020 中,引入了私有类变量以仅允许在类中使用变量。通过在我们的变量或函数前面添加一个简单的哈希符号,您可以将它们完全保留给类内部。
讯享网 class User {
#message = "Welcome to ES2020" login() {
console.log(this.#message) } } const user = new User() user.login() // Welcome to ES2020 console.log(user.#message) // Uncaught SyntaxError: Private field '#
ES9
2018 年 6 月发布
1. 异步迭代对象
function getPromise(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time) }, time) }) } let arr=[getPromise(100),getPromise(200),getPromise(300)] for(const i of arr){
console.log(i) } // Promise{<pending>} // Promise{<pending>} // Promise{<pending>}
异步for-await-of可以做到串行的。
讯享网function getPromise(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time) }, time) }) } let arr=[getPromise(100),getPromise(200),getPromise(300)] for await (const i of arr){
console.log(i) } //100 //200 //300
2. 对象扩展符
es6支持数组的扩展符,比如以下代码
function myfunc(p1, p2, ...p3) {
console.log(p1, p2, p3); // 1, 2, [3, 4, 5, 6] } myfunc(1, 2, 3, 4, 5, 6);
讯享网 const myArray = [10, 5, 25, -100, 200, -200]; console.log( Math.max(...myArray) ); // 200
现在es9支持对象扩展符

function myfunc1({
a, ...x }) {
console.log(a, x); // 1, { b: 2, c: 3, d:4 } } myfunc1({
a: 1, b: 2, c: 3, d: 4 });
讯享网const myObject = {
a: 1, b: 2, c: 3, d:4 }; const myNewObject = {
...myObject, e: 5 }; // { a: 1, b: 2, c: 3, d: 4, e: 5 }
3. Promise finally
有时您可能需要避免 then() 和 catch() 方法中的重复代码。
myPromise .then(result => {
// process the result and then clean up the resources }) .catch(error => {
// handle the error and then clean up the resources });
如果您希望在 promise 确定(即履行或拒绝)后进行一些处理或资源清理,则该方法很有用。
讯享网 let isLoading = true; fetch('http://somesite.com/users') .then(data => data.json()) .catch(err => console.error(err)) .finally(() => {
isLoading = false; console.log('Finished loading!!'); })
ES8
2017 年 6 月发布
1. Async functions
es6为了解决回调地狱的问题,增加了promise函数来解决,但promise又带来了新问题,那就是链条过长,导致难维护。
new Promise((resolve, reject) => {
this.login(resolve)}) .then(() => this.getInfo()) .then(() => {
// do something}) .catch(() => {
console.log("Error") })
于是又诞生了Generator函数,允许按需执行任务,通过yield和next来管理和执行任务,但流程依然不够清晰
讯享网const gen = function* () {
const f1 = yield this.login() const f2 = yield this.getInfo() };
现在,es8提供async/await,以其极简的语法来完成异步任务
async function logger() {
let data = await fetch('http://someapi.com/users'); // pause until fetch returns console.log(data) } logger();
2. Object.values()
与遍历 JavaScript 对象的键的 Object.keys 类似,Object.values 将对值做同样的事情。即,引入了 Object.values() 方法,以与循环相同的顺序返回给定对象自身的可枚举属性值的数组for…in
讯享网 const countries = {
IN: 'India', SG: 'Singapore', } Object.values(countries) // ['India', 'Singapore']
非对象参数将被强制转换为对象
console.log(Object.values(['India', 'Singapore'])); // ['India', 'Singapore'] console.log(Object.values('India')); // ['I', 'n', 'd', 'i', 'a']
3. Object.entries()
引入该Object.entries()方法以返回给定对象自身的可枚举字符串键控属性 [key, value] 对的数组,其顺序与for…in循环相同。
讯享网 const countries = {
IN: 'India', SG: 'Singapore', } Object.entries(countries) // [["IN", "India"], ["SG", "Singapore"]]
非对象参数将被强制转换为对象
const countriesArr = ['India', 'Singapore']; console.log(Object.entries(countriesArr)); // [ ['0', 'India'], ['1', 'Singapore']] const country = 'India'; console.log(Object.entries(country)); // [["0", "I"], ["1", "n"], ["2", "d"], ["3", "i"], ["4", "a"]] console.log(Object.entries(100)); // [], an empty array for any primitive type because it won't have any own properties
4. Object property descriptors
5. String padding
一些字符串和数字(金钱、日期、计时器等)需要以特定格式表示。引入的这两种padStart() & padEnd()方法都是用另一个字符串填充一个字符串,直到结果字符串达到提供的长度。
讯享网const cardNumber = '034'; const lastFourDigits = cardNumber.slice(-4); const maskedCardNumber = lastFourDigits.padStart(cardNumber.length, '*'); console.log(maskedCardNumber); // expected output: "1234"
const label1 = "Name"; const label2 = "Phone Number"; const value1 = "John" const value2 = "(222)-333-3456"; console.log((label1 + ': ').padEnd(20, ' ') + value1); // Name: John console.log(label2 + ": " + value2); // Phone Number: (222)-333-3456
ES7
2016 年 6 月发布
1. includes
在 ES7 之前,您必须使用indexOf方法将结果与 ‘-1’ 进行比较,以检查数组元素是否包含特定元素。
讯享网 const array = [1,2,3,4,5,6]; if(array.indexOf(5) > -1 ){
console.log("Found an element"); }
而在 ES7 中,array.prototype.includes()方法被引入作为一种直接方法来确定数组是否在其条目中包含某个值。
const array = [1,2,3,4,5,6]; if(array.includes(5)){
console.log("Found an element"); }
除此之外,它Array.prototype.includes()比方法更好地处理 NaN 和 Undefined 值Array.prototype.indexOf()。即,如果数组包含 NaN 和 Undefined 值,则indexOf()在搜索 NaN 和 Undefined 时不会返回正确的索引。
讯享网let numbers = [1, 2, 3, 4, NaN, ,]; console.log(numbers.indexOf(NaN)); // -1 console.log(numbers.indexOf(undefined)); // -1
另一方面,includes方法能够找到这些元素
let numbers = [1, 2, 3, 4, NaN, ,]; console.log(numbers.includes(NaN)); // true console.log(numbers.includes(undefined)); // true
2. 指数运算符
旧版本的 javascript 使用Math.pow函数来查找给定数字的幂。ECMAScript 2016 引入了求幂运算符 (类似于其他语言,例如 Python 或 F#),使用中缀表示法以清晰的表示形式计算幂计算。
讯享网//Prior ES7 const cube = x => Math.pow(x, 3); console.log(cube(3)); // 27 //Using ES7 const cube1 = x => x 3; console.log(cube1(3)); // 27
ES6
2015 年 6 月发布
因为tc39早期团队内的分歧严重,导致es6在接近十年后才能发布。
1. 变量作用域
变量作用域确定变量在程序或区域的特定部分内的可见性或可访问性。
在 ES6 中,关键字const和let关键字都允许开发人员在块范围内声明变量。
该let语句声明了一个可以重新分配的块作用域局部变量。即,let声明创建一个可变变量。
let a = 1; if (a === 1) {
let a = 2; console.log(a); //2 } console.log(a); //1
const变量类似于let变量,但它们不能通过重新分配来更改。即,const 声明创建一个对值的只读引用。
讯享网const x = 1; if (x === 1) {
const y = 2; // You cannot re-assign the value similar to let variable console.log(y); //2 } console.log(x); //1
const和let与var的区别
const
var定义的变量,可以预解析提前调用的结果是undefined,const定义的变量不能预解析,提前调用的结果是 报错。
var定义的变量,变量名称可以重复,效果是重复赋值,const定义的变量不能重复,否则执行报错。
var定义的变量作用域是全局/局部作用域。const定义的变量如果在{}中只能在{}中调用。
const 定义的变量存储的数据数值不能改变,也就是const定义的变量,不能重复赋值。
let
var定义的变量,可以预解析提前调用的结果是undefined,let定义的变量不能预解析,提前调用的结果是 报错。
var定义的变量,变量名称可以重复,效果是重复赋值,let定义的变量不能重复,否则执行报错。
var定义的变量作用域是全局/局部作用域。let定义的变量如果在{}中只能在{}中调用。
在循环语句中var定义的循环变量和使用let定义的循环变量。执行原理和执行效果不同。
2. 箭头函数
// Function Expression var multiplyFunc = function(a, b) {
return a * b; } console.log(multiplyFunc(2, 5)); // 10 // Arrow function var multiplyArrowFunc = (a, b) => a * b; console.log(multiplyArrowFunc(2, 5)); // 10
如果函数只有一个参数(零个或多个参数),您也可以跳过圆括号 (())。除此之外,如果函数体内有多个表达式,您可以用大括号 ({}) 括起来。
让我们列出箭头函数的所有变体
讯享网//1. Single parameter and single statement const message = name => console.log("Hello, " + name + "!"); message("Sudheer"); // Hello, Sudheer! //2. Multiple parameters and single statement const multiply = (x, y) => x * y; console.log(multiply(2, 5)); // 10 //3. Single parameter and multiple statements const even = number => {
if(number%2) {
console.log("Even"); } else {
console.log("Odd"); } } even(5); // odd //4. Multiple parameters and multiple statements const divide = (x, y) => {
if(y != 0) {
return x / y; } } console.log(divide(100, 5)); // 20 //5. No parameter and single statement const greet = () => console.log('Hello World!'); greet(); // Hello World!
3. 类
这些类作为现有基于原型的继承和构造函数的语法糖引入。所以这个特性并没有给 JavaScript 带来新的面向对象的继承模型。
有两种定义类的方法
类声明
class Square {
constructor(length) {
this.length = length; } get area() {
return this.length * this.length; } set area(value) {
this.area = value; } }
类表达式
const square = class Square {
constructor(length) {
this.length = length;
}
get area() {
return this.length * this.length;
}
set area(value) {
this.area = value;
}
}
您可以使用extend关键字来使用继承。这使子类能够获得父类的所有功能。
讯享网class Vehicle {
constructor(name) {
this.name = name; } start() {
console.log(`${
this.name} vehicle started`); } } class Car extends Vehicle {
start() {
console.log(`${
this.name} car started`); } } const car = new Car('BMW'); console.log(car.start()); // BMW car started
4. 增强的对象字面量
对象文字被扩展以支持在构造时设置原型、foo 的简写:foo 赋值、定义方法、进行超级调用以及使用表达式计算属性名称。
属性简写
var a = 1, b = 2, c = 3, obj = {
a: a, b: b, c: c }; console.log(obj);
它可以用更短的语法表示,如下所示
讯享网const a = 1, b = 2, c = 3; const obj = {
a, b, c }; console.log(obj);
方法速记
在 ES5 中,对象方法需要如下函数语句
var calculation = {
sum: function(a, b) {
return a + b; }, multiply: function(a, b) {
return a * b; } }; console.log(calculation.sum(5, 3)); // 8 console.log(calculation.multiply(5, 3)); // 15
这在 ES6 中可以避免
讯享网const calculation = {
sum(a, b) {
return a + b; }, multiply(a, b) {
return a * b; } }; console.log(calculation.sum(5, 3)); // 8 console.log(calculation.multiply(5, 3)); // 15
在 ES5 中,不可能在对象创建阶段使用变量作为键名。
var key = 'three', obj = {
one: 1, two: 2 }; obj[key] = 3;
在 ES6 中,可以通过将表达式放在方括号 ([]) 中来动态分配对象键
讯享网const key = 'three', computedObj = {
one: 1, two: 2, [key]: 3 };
5. 模板字符串
模板字面量
跨多行存在的字符串字面量,包括内插表达式(即 ${expression})。
const firstName = 'John'; console.log(`Hello ${
firstName}! Good morning!`);
标记的模板文字
通过在模板文字之前提及函数而创建的函数调用。
讯享网const Button = styled.a` display: inline-block; border-radius: 3px; `
6. 解构赋值
解构是一种 javascript 表达式,用于从存储在对象(对象的属性)和数组中的数据中提取多个值。
对象解构
此功能用于从对象中提取值。
const user = {
firstName: 'John', lastName: 'Kary' }; const {
firstName, lastName} = user; console.log(firstName, lastName); // John, Kary
数组解构
此功能用于从数组中提取值。
讯享网const [one, two, three] = ['one', 'two', 'three']; console.log(one, two, three); // one, two, three
还可以应用在以下地方
- 变量声明
- 对象分配
- 参数定义
- for循环
7. 参数默认值
function add(a, b) {
a = (typeof a !== 'undefined') ? a : 10; b = (typeof b !== 'undefined') ? b : 20; return a + b; } add(20); // 40 add(); // 30
在 ES6 中,可以使用默认参数避免这些检查。
讯享网function add(a = 10, b = 20) {
return a + b; } add(20); // 40 add(); // 30
8. 剩余参数
rest 参数用于将不定数量的参数表示为数组。这里的重点是只有函数的最后一个参数可以是“剩余参数”。引入此功能是为了减少由参数引起的样板代码。
function sum(...args) {
return args.reduce((previous, current) => {
return previous + current; }); } console.log(sum(1, 2, 3)); // 6 console.log(sum(1, 2, 3, 4)); // 10 console.log(sum(1, 2, 3, 4, 5)); // 15
9. 数组伸展符
在函数和构造函数调用中,展开运算符将可迭代值转换为参数。
讯享网console.log(Math.max(...[-10, 30, 10, 20])); //30 console.log(Math.max(-10, ...[-50, 10], 30)); //30
在数组文字和字符串中,扩展运算符将可迭代值转换为数组元素。
console.log([1, ...[2,3], 4, ...[5, 6, 7]]); // 1, 2, 3, 4, 5, 6, 7
10. 数组迭代器和forof
String、Array、TypedArray、Map 和 Set 都是内置的可迭代对象,但默认情况下对象不是可迭代的。迭代器是一种循环遍历 JavaScript 中任何集合的新方法。这些对象定义了一个序列,并可能在其终止时返回一个值。迭代器通过具有返回具有两个属性的对象的 next() 方法来实现 Iterator 协议。
您可以通过在其上定义属性来使对象可迭代Symbol.iterator。
讯享网const collection = {
one: 1, two: 2, three: 3, [Symbol.iterator]() {
const values = Object.keys(this); let i = 0; return {
next: () => {
return {
value: this[values[i++]], done: i > values.length } } }; } }; const iterator = collection[Symbol.iterator](); console.log(iterator.next()); // → {value: 1, done: false} console.log(iterator.next()); // → {value: 2, done: false} console.log(iterator.next()); // → {value: 3, done: false} console.log(iterator.next()); // → {value: undefined, done: true} for (const value of collection) {
console.log(value); }
11. Generators
function* myGenerator(i) {
yield i + 10; yield i + 20; return i + 30; } const myGenObj = myGenerator(10); console.log(myGenObj.next().value); // 20 console.log(myGenObj.next().value); // 30 console.log(myGenObj.next().value); // 40
12. module
重量级特性
模块是独立的、可重复使用的代码的小单元,用作 Javascript 应用程序中的构建块。
在 ES6 之前,JavaScript 中没有原生模块支持。使用了 3 个主要的模块标准。
- 异步模块定义 (AMD)
- RequireJS 模块
- CommonJS 模块(在 Node.js 中使用的 module.exports 和 require 语法)
es6 提供了对模块的内置支持。默认情况下,模块内的所有内容都是私有的,并以严格模式运行。公共变量、函数和类都使用 usingexport语句公开并导入相同的 usingimport语句。
和过去的commonjs规范有什么区别?
- module属于编译时加载,也就是静态加载,在编译时就能确定模块的依赖关系,以及输入和输出的变量;commonjs属于运行时加载,只有代码在运行时才能确定这些东西。
- module可以做到tree-shaking,也就是可以加载模块部分用到的内容,commonjs需要加载整个模块,再取内容。
- module输出的是值的引用,commonjs输出的是值的拷贝。
- module中的import是异步加载,commonjs中的require是同步加载
export声明
讯享网// module "my-module.js" const PI = Math.PI; function add(...args) {
return args.reduce((num, tot) => tot + num); } function multiply(...args) {
return args.reduce((num, tot) => tot * num); } // private function function print(msg) {
console.log(msg); } export {
PI, add, multiply };
// module "my-module.js" export default function add(...args) {
return args.reduce((num, tot) => tot + num); }
import声明
讯享网// 1. Import an entire module's contents import * as name from "my-module"; //2.Import a single export from a module import {
export1 } from "my-module"; //3.Import multiple exports from a module import {
export1 , export2 } from "my-module"; //4.Import default export from a module import defaultExport from "my-module"; //5.Import an export with an alias import {
export1 as alias1 } from "my-module";
13 set
Set 是一个内置对象,用于存储任何类型的唯一值的集合。
let mySet = new Set() mySet.add(1); mySet.add(2); mySet.add(2); mySet.add('some text here'); mySet.add({
one: 1, two: 2 , three: 3}); console.log(mySet); // Set [ 1, 2, 'some text here', {one: 1, two: 2 , three: 3} ] console.log(mySet.size) // 4 console.log(mySet.has(2)); // true
14. map
Map 是元素的集合,其中每个元素都存储为键值对。它可以将对象和原始值作为键或值保存,并按插入顺序迭代其元素。
讯享网let typeMap = new Map(); var keyObj = {
'one': 1} typeMap.set('10', 'string'); // a string key typeMap.set(10, 'number'); // a numeric key typeMap.set(true, 'boolean'); // a boolean key typeMap.set(keyObj, 'object'); // an object key console.log(typeMap.get(10)); // number console.log(typeMap.get('10')); // string console.log(typeMap.get(keyObj)); // object console.log(typeMap.get({
'one': 1})); // undefined console.log(typeMap.size ); // 3 for(let item of typeMap) {
console.log(item); } for(let item in typeMap) {
console.log(item); }
15. Symbol
16. promise
Promise 是一个对象,表示异步操作的最终完成或失败。
它处于以下状态之一:
pending:代表初始状态,既没有完成也没有被拒绝。 fulfilled:表示操作成功完成。 rejected:表示操作失败。
如果一个承诺要么被履行要么被拒绝,但不是未决的,就被称为已解决。实例方法promise.then()、promise.catch()和promise.finally()用于将进一步的操作与已确定的承诺相关联。这些方法还返回一个新生成的 promise 对象,它可以选择性地用于链接。

const promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); }); promise.then(function(result) {
console.log(result); // 1 return result * 2; }).then(function(result) {
console.log(result); // 2 return result * 3; }).then(function(result) {
console.log(result); // 6 return result * 4; }).catch(function(error){
console.log(error); });
17. 数组方法
S6 引入了一些数组方法,其中两个是Array.find()和Array.findIndex()。
ES5
w3schools
2009年年中发布

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/35835.html