ES6 新特性
声明变量
let a;
let b,c,d;
变量不可以重复声明,没有声明前不允许使用,不像var是跨域
6 种 声明变量 var 命令,function,let,const import class命令
变量解构赋值
可以快速赋值,快速读取参数不用赋值
1.交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
2.从函数里返回多个值
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
3.传递实参
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
4.提取json数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
5.快速遍历Map结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
6.只是获取键名,和键值
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
块级作用域,全局,函数,eval
这里变量的作用域是let 变量的作用域
块级作用域可以将变量作用范围固定在作用域内
下一级依然可以往上找
if for等的{}
{
}
常量声明
一定要声明变量值
const常量名=变量值;
常量名用大写,常量不可修改也是受块级作用域约束,const 可以定义数组名 const 的地址指向不能变化
字符串的拓展
使用反引号进行框起字符串可以默认直接进行字符串拼接与换行拼接
let lovest=“xxx”;
let out =${lovest}xxx;
字符串遍历方式
for (let codePoint of 'foo') {
console.log(codePoint)
}
码点识别
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);
}
模板字符串
用反引号包裹字符串,使用${name} 占位显示,内容里要使用反引号就要用 / 标记里面可以也可使用 js 表达式,也可以传入js 变量
RegExp 构造函数
正则表达式的创建
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
//或者是
var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;
正则表达式新修饰符 u 用于处理 unicode 编码,用于处理大于 \ufff 的 Unicode 字符
g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始
String.prototype.matchAll()
遍历匹配正则到就可以输出正则匹配项
const string = 'test1test2test3';
const regex = /t(e)(st(\d?))/g;
for (const match of string.matchAll(regex)) {
console.log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
数值的拓展
当位数较多的时候就可以使用 下滑线分割位数
let budget = 1_000_000_000_000;
budget === 10 ** 12 // true
let budget = 1_000_000_000_000;
budget === 10 ** 12 // true
Number.parseInt(), Number.parseFloat()
// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
Number.isInteger()
判断是否为整数
Number.isInteger(25) // true
Number.isInteger(25.1) // false
函数的拓展
允许在参数设置里面 设置一个默认值
箭头函数
(形参) =》{函数体} 没有形参打个括号就行 没有返回值的简写时不要写花括号
let foo = () => { a: 1 };
foo() // undefined
var sum =(num1,num2) =>{return num1+num2;}
// 只有一个形参的时候,并且只有一个返回的时候就可以使用下面的简写形式
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
//使用结构写法
let fn = () => void doesNotReturn();
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
1.箭头函数 没有自己的this 对象
2.不可作为构造函数(这里只是一个函数)
3.不可以使用 arguments 对象
4.不可以使用 yield 命令 不能用作Generator
setTimeout() setInterval() 等 回调函数可以使用箭头函数
箭头函数的this 总是指向外层的包裹的函数
如果函数是一个回调函数,this是指向箭头函数外层的对象
因此不要作为成员函数
尾调用
return 函数名(形参)
尾递归
在结尾进行递归
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
factorial(5) // 120
catch 命令的参数省略
try {
// ...
} catch (err) {
// 处理错误
}
// 如果没有用 err 信息就可以简写
try{}
catch{
}
数组的拓展
参数 数量拓展 ... 输入形参以后会自动匹配 对应的数量 也可以将一个数组转化为一个函数的形参
可以对数组进行拆解拷贝,但是是浅拷贝
// ES5 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6 的写法
function f(x, y, z) {
// ...
}
let args = [0, 1, 2];
f(...args);
// 将数组拆解并且从新赋值
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
将伪数组变为真数组
在es6 中有一个这样API Array.from 比如说把一些 querySelectorAll() 变为类似的数组对象
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5 的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6 的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
多个形参的时候可以传入 回调函数对伪数组里的数进行处理
Array .of()
Array of( )方法将一组值变为数组
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
实例方法 copyWithin
数组实例的copyWithin()方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。
- target(必需):从该位置开始替换数据。如果为负值,表示倒数。
- start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
- end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
实例方法 find(),findIndex(),findLast(),findLastIndex()
find 是可以找到符合回调函数的的 数组对象返回
[1, 4, -5, 10].find((n) => n < 0)
// -5
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
// findIndex方法 与 find 方法类似
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
这个方法可以接受两个参数,用来绑定回调 函数的this对象
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26
find()和findIndex()都是从数组的0号位,依次向后检查。ES2022 新增了两个方法findLast()和findLastIndex(),从数组的最后一个成员开始,依次向前检查,其他都保持不变。
fill() 方法
fill方法使用给定值,填充一个数组。
常用与初始化数组
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2) // 第二个参数用于绑定起始位置,第三个参数表示结束位置
entries(),keys() 和 values()
遍历器 for of循环遍历,可以遍历 keys() 对键名 values对 键值的遍历 entries 是对整个键值对
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
实例方法 includes
表示某一个数组是否包含某个字符串或者是 数字
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
flat() flatMap()
将一个二维数组拉平为一维数组,默认拉一层,可以设置层数
[1, 2, [3, 4]].flat()
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
//无限拉平
[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]
at 索引
const arr = [5, 12, 8, 130, 44];
arr.at(2) // 8
arr.at(-2) // 130
在不改变原数组的情况下变化数组
数组调整方法 翻转,排序等
很多数组的传统方法会改变原数组,比如push()、pop()、shift()、unshift()等等。数组只要调用了这些方法,它的值就变了。现在有一个提案,允许对数组进行操作时,不改变原数组,而返回一个原数组的拷备
Array.prototype.toReversed() -> ArrayArray.prototype.toSorted(compareFn) -> ArrayArray.prototype.toSpliced(start, deleteCount, ...items) -> ArrayArray.prototype.with(index, value) -> Array
const sequence = [1, 2, 3];
sequence.toReversed() // [3, 2, 1]
sequence // [1, 2, 3]
const outOfOrder = [3, 1, 2];
outOfOrder.toSorted() // [1, 2, 3]
outOfOrder // [3, 1, 2]
const array = [1, 2, 3, 4];
array.toSpliced(1, 2, 5, 6, 7) // [1, 5, 6, 7, 4]
array // [1, 2, 3, 4]
const correctionNeeded = [1, 1, 3];
correctionNeeded.with(1, 2) // [1, 2, 3]
correctionNeeded // [1, 1, 3]
数组成员分组
数组成员分组是一个常见需求,比如 SQL 有GROUP BY子句和函数式编程有 MapReduce 方法。现在有一个提案,为 JavaScript 新增了数组实例方法group()和groupToMap(),它们可以根据分组函数的运行结果,将数组成员分组。group()的参数是一个分组函数,原数组的每个成员都会依次执行这个函数,确定自己是哪一个组。
稳定排序:
const arr = [
'peach',
'straw',
'apple',
'spork'
];
const stableSorting = (s1, s2) => {
if (s1[0] < s2[0]) return -1;
return 1;
};
arr.sort(stableSorting)
// ["apple", "peach", "straw", "spork"]
对象的拓展
允许赋值写入对象
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};
允许直接写变量在对象里面
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
方法也可以省略键值对
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};