您现在的位置是:首页 >学无止境 >ES6至ES12网站首页学无止境
ES6至ES12
ES6至ES12
原文地址:https://mp.weixin.qq.com/s/knmV9Y6FkC33dtaM9R3Rqg
ES6
1、let 和 const
2、默认参数
开发中你曾遇到过这样的问题,如果参数不传进来,你就设置默认参数
function fn (name, age) {
var name = name || 'jack'
var age = age || 18
console.log(name, age)
}
fn() // 林三心 18
块级作用域解决问题:
function fn (name = 'jack', age = 18) {
console.log(name, age)
}
fn() // jack 18
fn('sunshine', 22) // sunshine 22
3、扩展运算符
曾经想要拼接多个数组只能这么做
const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]
const arr = arr1.concat(arr2).concat(arr3)
[
1, 2, 4, 4, 5,
7, 7, 8, 9
]
现在
const arr1 = [1, 2, 4]
const arr2 = [4, 5, 7]
const arr3 = [7, 8, 9]
const arr = [...arr1, ...arr2, ...arr3]
[
1, 2, 4, 4, 5,
7, 7, 8, 9
]
4、剩余参数
function fn (name, ...params) {
console.log(name)
console.log(params)
}
fn ('林三心', 1, 2) // 林三心 [ 1, 2 ]
fn ('林三心', 1, 2, 3, 4, 5) // 林三心 [ 1, 2, 3, 4, 5 ]
5、模板字符串
const name = '林三心'
const age = '22'
console.log(`${name}今年${age}岁啦`) // 林三心今年22岁啦
6、Object.keys
可以用来获取对象的key的集合,进而可以获得对应key的value
const obj = {
name: 'jack',
age: 22,
gender: '男'
}
const keys = Object.keys(obj)
console.log(keys) // [ 'name', 'age', 'gender' ]
7、箭头函数
const fn = () => {}
// 如果只有一个参数,可以省略括号
const fn = name => {}
// 如果函数体里只有一句return
const fn = name => {
return 2 * name
}
// 可简写为
const fn = name => 2 * name
// 如果返回的是对象
const fn = name => ({ name: name })
普通函数和箭头函数的区别:
- 1、箭头函数不可作为构造函数,不能使用new
- 2、箭头函数没有自己的this
- 3、箭头函数没有arguments对象
- 4、箭头函数没有原型对象
- 5、箭头函数不能改变this指向
8、Array.prototype.forEach
ES6新加的数组遍历方法
const eachArr = [1, 2, 3, 4, 5]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数
eachArr.forEach((item, index, arr) => {
console.log(item, index, arr)
})
1 0 [ 1, 2, 3, 4, 5 ]
2 1 [ 1, 2, 3, 4, 5 ]
3 2 [ 1, 2, 3, 4, 5 ]
4 3 [ 1, 2, 3, 4, 5 ]
5 4 [ 1, 2, 3, 4, 5 ]
9、Array.prototype.map
常用于返回一个处理过后的新数组
const mapArr = [1, 2, 3, 4, 5]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,对每一个元素进行翻倍
const mapArr2 = mapArr.map((num, index, arr) => 2 * num)
console.log(mapArr2)
[ 2, 4, 6, 8, 10 ]
10、Array.prototype.filter
11、Array.prototype.some
some,意思就是只要有一个是真,那就返回真
const someArr = [false, true, false, true, false]
// 三个参数:遍历项 索引 数组本身
// 配合箭头函数,只要有一个为true,就返回true,一个都true都没有,就返回false
const someArr2 = someArr.some((bol, index, arr) => bol)
console.log(someArr2)
true
12、Array.prototype.every
every跟some是相反的,some是只要有一个就行,every是要所有为真才返回真
13、Array.prototype.reduce
// 计算 1 + 2 + 3 + 4 + 5
const reduceArr = [1, 2, 3, 4, 5]
const sum = reduceArr.reduce((pre, next) => {
return pre + next
}, 0)
console.log(sum) // 15
14、对象属性同名简写
const name = 'jack'
const age = '22'
// 属性同名可简写
const obj = {
name,
age
}
console.log(obj) // { name: 'jack', age: '22' }
15、Promise
16、class
17、解构赋值
const obj = {
name: 'jack',
age: 22,
gender: '男'
}
const { name, age, gender } = obj
也可以进行数组的解构
const arr = [1, 2, 3]
const [a, b, c] = arr
console.log(a, b, c) // 1 2 3
18、find 和 findIndex
find()
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
。
- find:找到返回被找元素,找不到返回undefined
- findIndex:找到返回被找元素索引,找不到返回-1
19、for of 和 for in
for ... in
是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()
和for ... of
,
20、Set 和 Map
Set有点类似于Array数组*,但是和数组的区别是Set的元素不能重复*
set()常用功能就是数组去重
const arr = [1, 2, 3, 4, 4, 5, 5, 66, 9, 1]
// Set可利用扩展运算符转为数组哦
const quchongArr = [...new Set(arr)]
console.log(quchongArr) // [1, 2, 3, 4, 5, 66, 9]
Map Map
对比object
最大的好处就是,key不受类型限制
一个 Object
的键必须是一个 String
或是 Symbol
。
// 定义map
const map1 = new Map()
// 新增键值对 使用 set(key, value)
map1.set(true, 1)
map1.set(1, 2)
map1.set('哈哈', '嘻嘻嘻')
console.log(map1) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }
// 判断map是否含有某个key 使用 has(key)
console.log(map1.has('哈哈')) // true
// 获取map中某个key对应的value 使用 get(key)
console.log(map1.get(true)) // 2
// 删除map中某个键值对 使用 delete(key)
map1.delete('哈哈')
console.log(map1) // Map(2) { true => 1, 1 => 2 }
// 定义map,也可传入键值对数组集合
const map2 = new Map([[true, 1], [1, 2], ['哈哈', '嘻嘻嘻']])
console.log(map2) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }
Map
中的键是有序的。因此,当迭代的时候,一个 Map
对象以插入的顺序返回键值。
Map
的键值对个数可以轻易地通过 size
属性获取。Object
的键值对个数只能手动计算。
Map
是 可迭代的 的,所以可以直接被迭代。Object
没有实现 迭代协议,所以使用 JavaSctipt 的 for…of 表达式并不能直接迭代对象。
Map在频繁增删键值对的场景下表现更好。Object在频繁添加和删除键值对的场景下未作出优化。
ES7
1、includes
传入元素,如果数组中能找到此元素,则返回true,否则返回false
跟indexOf很像,但还是有区别的
const arr = [1, 2, NaN]
console.log(arr.indexOf(NaN)) // -1 indexOf找不到NaN
console.log(arr.includes(NaN)) // true includes能找到NaN
2、求幂运算符
以前求幂,我们需要这么写
const num = Math.pow(3, 2) // 9
const num = 3 ** 2 // 9
ES8
1、Object.values
const obj = {
name: 'jack',
age: 22,
gender: '男'
}
const values = Object.values(obj)
console.log(values) // [ 'jack', 22, '男' ]
2、Object.entries
可以用来获取对象的键值对集合
const obj = {
name: 'jack',
age: 22,
gender: '男'
}
const entries = Object.entries(obj)
console.log(entries)
// [ [ 'name', 'jack' ], [ 'age', 22 ], [ 'gender', '男' ] ]
3、async/await
这个是很常用的语法了,我的理解就是:以同步方式执行异步操作
ES9
1、for await of
function fn (time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time}毫秒后我成功啦!!!`)
}, time)
})
}
async function asyncFn () {
const arr = [fn(3000), fn(1000), fn(1000), fn(2000), fn(500)]
for await (let x of arr) {
console.log(x)
}
}
asyncFn()
3000毫秒后我成功啦!!!
1000毫秒后我成功啦!!!
1000毫秒后我成功啦!!!
2000毫秒后我成功啦!!!
500毫秒后我成功啦!!!
2、Promise.finally
新增的Promise方法,无论失败或者成功状态,都会执行这个函数
ES10
1、Array.flat
有一个二维数组,我想让他变成一维数组:
const arr = [1, 2, 3, [4, 5, 6]]
console.log(arr.flat()) // [ 1, 2, 3, 4, 5, 6 ]
2、Array.flatMap
let arr = ["科比 詹姆斯 安东尼", "利拉德 罗斯 麦科勒姆"];
转化为
[ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
第一时间想到map + flat
console.log(arr.map(x => x.split(" ")).flat());
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
flatMap
就是flat + map
,一个方法顶两个
console.log(arr.flatMap(x => x.split(" ")));
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
3、BigInt
BigInt
是ES10新加的一种JavaScript数据类型,用来表示表示大于 2^53 - 1
的整数,2^53 - 1
是ES10之前,JavaScript所能表示最大的数字
所以以后面试官问你JavaScript有多少种数据类型,别傻傻答6种了,要答8种,把ES6的Symbol
和ES10的BigInt
也加上去
4、Object.fromEntries
前面ES8的Object.entries
是把对象转成键值对数组
,而Object.fromEntries
则相反,是把键值对数组转为对象
const arr = [
['name', 'jack'],
['age', 22],
['gender', '男']
]
console.log(Object.fromEntries(arr)) // { name: 'jack', age: 22, gender: '男' }
他还有一个用处,就是把Map转为对象
const map = new Map()
map.set('name', '林三心')
map.set('age', 22)
map.set('gender', '男')
console.log(map) // Map(3) { 'name' => '林三心', 'age' => 22, 'gender' => '男' }
const obj = Object.fromEntries(map)
console.log(obj) // { name: '林三心', age: 22, gender: '男' }
5、String.trimStart && String.trimEnd
咱们都知道JavaScript有个trim方法,可以清除字符串首尾的空格
const str = ' jack '
console.log(str.trim()) // 'jack'
trimStart和trimEnd用来单独去除字符串的首和尾的空格
ES11
1、Promise.allSettled
ES11新增的Promise的方法
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 把每一个Promise的结果,集合成数组,返回
ES12
1、Promise.any
E12新增的Promise的方法
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 如果有一个Promise成功,则返回这个成功结果
- 如果所有Promise都失败,则报错
Symbol的使用
应用场景1:使用Symbol来作为对象属性名
平常我们对象的属性都是字符串
const obj = {
name: 'jack',
age: 23
}
console.log(obj['name']) // 'jack'
console.log(obj['age']) // 23
其实也可以用Symbol来当做属性名
const gender = Symbol('gender')
const obj = {
name: 'jack',
age: 23,
[gender]: '男'
}
console.log(obj['name']) // 'jack'
console.log(obj['age']) // 23
console.log(obj[gender]) // 男
但是Symbol作为属性的属性不会被枚举出来,这也是JSON.stringfy(obj)
时,Symbol属性会被排除在外的原因
其实想获取Symbol属性也不是没办法。
// 方法一
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(gender) ]
// 方法二
console.log(Reflect.ownKeys(obj)) // [ 'name', 'age', Symbol(gender) ]
应用场景2:使用Symbol定义类的私有属性
以下例子,PASSWORD属性无法在实例里获取到
class Login {
constructor(username, password) {
const PASSWORD = Symbol()
this.username = username
this[PASSWORD] = password
}
checkPassword(pwd) { return this[PASSWORD] === pwd }
}
const login = new Login('123456', 'hahah')
console.log(login.PASSWORD) // 报错
console.log(login[PASSWORD]) // 报错
console.log(login[PASSWORD]) // 报错