赞
踩
ECMAScript 6(简称 ES6)是 JavaScript 的一个版本,也被称为 ECMAScript 2015。它是 JavaScript 的一个标准规范,提供了一系列新的语法和 API,用于帮助开发者更加轻松、高效地编写 JavaScript 代码。
let 命令声明一个变量,可以修改。
const 命令声明一个常量,声明之后不允许修改,因此 const 一旦声明变量,就必须立即初始化,不能留到以后赋值。
const 实际上保证的,并不是变量的值不变,而是变量指向的内存地址所存储的数据不变。对基础数据类型,值就存储在变量指向的内存地址,因此相当于常量。对于引用数据类型,变量指向的内存地址,存储的只是一个指向实际数据的指针。const 只能保证这个指针是固定的,至于它指向的数据结构就不能控制了。所以 const 声明的数组和对象,可以增减元素和属性。
要点(和 var 的不同):
不存在变量提升,变量一定要在声明之后才能使用。
块级作用域:let 和 const 声明的变量只在它所在的代码块有效。因此,for 循环的计数器很适合使用 let 命令。
const f = () => {
let x = 1; // 只在 f 函数内有效
if (true) {
let x = 2; // 只在 if 语句块内有效
const y = 'hello world !';
console.log(x); // 输出 2
}
console.log(x); // 输出 1
console.log(y); // ReferenceError: y is not defined
}
f();
在同一作用域下,不能重复声明同一个变量。
暂时性死区:是指在代码块中,在变量声明语句之前使用该变量会导致 ReferenceError 错误的现象。
在代码块中,如果使用 let 或 const 声明一个变量,那么这个变量会从开始执行该代码块的时间开始进入暂时性死区,直到声明语句完成为止。在这个时期内,如果使用该变量,将会触发 ReferenceError 错误。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值。本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于 undefined。
数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let [x = 1, y = x] = [2]; // x = 2, y = 2
let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; // bar = 'bbb', foo = 'aaa'
实际上,对象的解构赋值是let {bar: bar, foo: foo} = { foo: 'aaa', bar: 'bbb'};
的简写形式。对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
// bar是匹配的模式,foo才是变量,真正被赋值的是变量foo
let { bar: foo } = { foo: 'aaa', bar: 'bbb' }; // foo = 'bbb'
${}
之中。let s = 'hello, world!';
s.includes('ll'); //true
s.startsWith('hello'); //true
s.endsWith('!'); //true
// 支持第二个参数,表示开始搜索的位置
replaceAll()
let s = 'abbc';
s.replace('b', '_'); // a_bc
s.replace(/b/g, '_'); // a__c
s.replaceAll('b', '_'); // a__c
// $&:匹配的字符串,即`b`本身
'abbc'.replaceAll('b', '$&'); // abbc
//$`:匹配结果前面的文本,对第一个b,指的是a,对第二个b,指的是ab
'abbc'.replaceAll('b', '$`'); // aaabc
// $':品牌结果后面的文本
'abbc'.replaceAll('b', `b'`); // abccc
// $$:表示美元符号$
‘abbc’,replaceAll('b', '$$'); // a$$c
// $1表示正则表达式的第一组匹配'ab',$2指正则匹配第二组匹配'bc'
'abbc'.replaceAll(/(ab)(bc)/g, '$2$1'); // bcab
123_40 === 12_340 === 1234 * 10;
,但是,字符串转数值的函数不能使用数值分隔符parseInt('123_456') = 123;
。箭头函数:=>
ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。
const fetch = (url, {body = '', method = 'GET', headers = {}}) => {
console.log(method);
}
fetch('http://example.com', {}); // GET
fetch('http://example.com'); // 报错
以上代码中,fetch() 的第二个参数必须是对象,且不能省略,这样才能获取默认参数值,否则会报错。如果结合函数参数的默认值,就可以省略第二个参数。
const fetch = (url, {body = '', method = 'GET', headers = {}} = {}) => {
console.log(method);
}
fetch('http://example.com'); // GET
rest 参数:使用 (…变量名)的形式来获取函数的剩余参数 const sortNumbers = ( ... numbers) => numbers.sort();
...
,可以用于合并数组和函数调用。const add = (x, y) => x + y;
add( ...[2, 3]);
[1, 2, 3].includes(2);
const foo = 'abc';
const baz = { foo }; // { foo: 'abc' }
// 相当于const baz = { foo: foo };
[ ]
表达式let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word']; // hello
a[lastWord]; // world
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
let n = { ...{a: 2, b: 3} };
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
2 ** 2 = 4;
const firstName = message?.body?.user?.firstName || 'default';
const headerText = response.settings.headerText ?? 'Hello, world!';
,只有运算符左侧的值为 null 或 undefined 时,才会返回右侧的值。和 || 类似。但是 || 使用时,左侧为 0、 false、 空字符串、NaN、null、undefined时都返回右侧的值,判断更为宽松。const s = Symbol('foo');
s; // Symbol(foo)
typeof s; // 'symbol'
s.toString(); // 'Symbol(foo)'
s.description; // 'foo'
const s1 = Symbol('foo');
const s2 = Symbol('foo');
console.log(s1 === s2); // false
const name = Symbol('John');
let users = {
Alice: 12,
[name]: 13,
}
users; // {Alice: 12, Symbol(John): 13}
users[name] = 15; // {Alice: 12, Symbol(John): 15}
let s = new Set();
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)]; // [3, 5, 2]
let s = new Set();
s.add(1).add(2).add(2);
// 注意2被加入了两次
s.size // 2
s.has(2) // true
s.has(3) // false
s.delete(2) // true
s.has(2) // false
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
const map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
// 表面上是相同的键,但实际上是两个不同的数组实例,内存地址不同
Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
ES6 规定,Promise 对象是一个构造函数,用来生成 Promise 实例。并且,Promise 新建后就会立即执行。
const fetchData = new Promise((resolve, reject) => {
console.log('Promise'); // Promise新建后立即执行,输出'Promise'
setTimeout(() => { // 异步操作
const data = 'Some data';
if (data) {
resolve(data); // 异步操作成功时调用,使Promise的状态由pending转为resolved,并将异步操作的结果作为参数传递出去
} else {
reject('Error occurred'); // 异步操作失败时调用,使Promise的状态由pending转为rejected,并将错误信息作为参数传递出去
}
}, 2000);
});
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别为 resolve 和 reject,这两个参数也都是函数,由 JavaScript 引擎提供,不需要自己写,分别指异步操作成功和失败后的回调函数。
Promise 实例生成之后,可以用 then 方法指定 resolve 状态的回调函数,用 catch 方法指定 reject 状态的回调函数。
fetchData.then(data => { // Promise状态变为resolved之后触发then方法
console.log('Data:', data); // 输出 Data: Some data
}).catch(err => { // Promise状态变为rejected时触发catch方法
console.log('Error:', err);
})
一般来说,调用 resolve 或 reject 以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。
Promise 实例具有 then 方法,then 方法会返回一个新的 Promise 实例。因此,可以采用链式写法,then 方法后面再调用下一个 then 方法。
fetchData.then(data => {
fetchData(data.result)
}).then(comments => {
console.log("resolved: ", comments),
}).catch(err => {
console.log("rejected: ", err)
});
catch 方法放在最后,会捕捉前面所有异步操作的错误。
Generator 函数有两个特征。一是,function关键字与函数名之间有一个星号(*);二是,函数体内部使用 yield 表达式,定义不同的内部状态。
const fs = require('fs'); const readFile = fileName => { return new Promise((resolve, reject) => { fs.readFile(fileName, (error, data) => { if (error) return reject(error); resolve(data); }); }); }; const gen = function* () { const f1 = yield readFile('/etc/fstab'); const f2 = yield readFile('/etc/shells'); console.log(f1.toString()); console.log(f2.toString()); }; var co = require('co'); // co模块用于 Generator 函数的自动执行,返回一个Promise co(gen).then(() => { console.log('Generator 函数执行完成'); });
async 函数其实是 Generator 函数的语法糖,将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await 。而且 async 函数自带执行器,不需要 co 模块。
const asyncReadFile = async () => {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
};
asyncReadFile();
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。
const name = 'John';
const age = 18;
export {name, age};
// 还可以写成
export const name = 'John';
export const age = 18;
在一个文件或模块中,export 可以有多个。
export default const user = {
name: 'John',
age: 18
}
export default 指默认输出,一个文件或模块中只能有一个。
import {name, age as year} from './index.js'; // export和import都可以使用as重命名
import user from './index.js';
通过 export 导出,导入时需要 {}
,通过 export default 导出则不需要。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。