es7 es8 es9 es10 新增相关属性
1.include 的传入元素,如果数组中能找到此元素,则返回true,否则返回false
const includeArr = [1, 2 , 3, '林三心', '科比']
const isKobe = includeArr.includes('科比')
console.log(isKobe) // [true](url)
和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
3.Object.values
Object.keys
Object.enteries
可以用来获取对象的键值对集合
let obj={name:'张三',age:100}
cosnole.log(Object.enteries(obj))
// [['name','张三'],['age',100]]
4.for await of
我们来看以下场景哈
function fn(tm){
return new Promise((reslove,reject)=>{
setTimeOut(()=>{
reslove(console.log(`${tm}毫秒后我成功啦`))
},
tm)
})
}
fn(300)
fn(200)
fn(100)
期望打印结果:
300毫秒后我成功啦
200毫秒后我成功啦
100毫秒后我成功啦
然而实际打印结果:
300毫秒后我成功啦
200毫秒后我成功啦
100毫秒后我成功啦
第一时间我们肯定想到的是async/await
function fn (time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time}毫秒后我成功啦!!!`)
}, time)
})
}
async function asyncFn () {
// 排队
const data1 = await fn(3000)
console.log(data1) // 3秒后 3000毫秒后我成功啦!!!
const data2 = await fn(1000)
console.log(data2) // 再过1秒 1000毫秒后我成功啦!!!
const data3 = await fn(2000)
console.log(data3) // 再过2秒 2000毫秒后我成功啦!!!
}
但是上面代码也是有缺点的,如果有几十个,那不是得写几十个await,有没有一种方法可以通过循环来输出呢?
function fn (time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time}毫秒后我成功啦!!!`)
}, time)
})
}
async function asyncFn () {
const arr = [fn(300), fn(200), fn(100), fn(50)]
for await (let x of arr) {
console.log(x)
}
}
asyncFn()
300毫秒后我成功啦!!!
200毫秒后我成功啦!!!
100毫秒后我成功啦!!!
50毫秒后我成功啦!!!
5、Array.flat
有一个二维数组,我想让他变成一维数组:
const arr = [1, 2, 3, [4, 5, 6]]
console.log(arr.flat()) // [ 1, 2, 3, 4, 5, 6 ]
还可以传参数,参数为降维的次数
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
console.log(arr.flat(2))
[
1, 2, 3, 4, 5,
6, 7, 8, 9
]
如果传的是一个无限大的数字,那么就实现了多维数组(无论几维)降为一维数组
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]]
console.log(arr.flat(Infinity))
[
1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12
]
6、Array.flatMap
现在给你一个需求
let arr = ["科比 詹姆斯 安东尼", "利拉德 罗斯 麦科勒姆"];
将上面数组转为
[ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
第一时间想到map + flat
console.log(arr.map(x => x.split(" ")).flat());
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
flatMap就是flat + map,一个方法顶两个
console.log(arr.flatMap(x => x.split(" ")));
// [ '科比', '詹姆斯', '安东尼', '利拉德', '罗斯', '麦科勒姆' ]
9、Object.fromEntries
前面ES8的Object.entries是把对象转成键值对数组,而Object.fromEntries则相反,是把键值对数组转为对象
const arr = [ ['name', '林三心'],
['age', 22],
['gender', '男']
]
console.log(Object.fromEntries(arr)) // { name: '林三心', 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: '男' }
10、?. 和 ??
- 先说说
?.,中文名为可选链
比如我们需要一个变量,是数组且有长度,才做某些操作
const list = null
// do something
if (list && list.length) {
// do something
}
// 使用可选链
const list = null
// do something
if (list?.length) {
// do something
}
比如有一个对象,我要取一个可能不存在的值,甚至我们都不确定obj是否存在
const obj = {
cat: {
name: '哈哈'
}
}
const dog = obj && obj.dog && obj.dog.name // undefined
// 可选链
const obj = {
cat: {
name: '哈哈'
}
}
const dog = obj?.dog?.name // undefined
比如有一个数组,我不确定它存不存在,存在的话就取索引为1的值
const arr = null
// do something
const item = arr && arr[1]
// 可选链
const arr = null
// do something
const item = arr?.[1]
比如有一个函数,我们不确定它存不存在,存在的话就执行它
const fn = null
// do something
const res = fn && fn()
// 可选链
const fn = null
// do something
const res = fn?.()
- 再说说
??,中文名为空位合并运算符请看以下代码,咱们使用||运算符,只要左边是假值,就会返回右边的数据
const a = 0 || '林三心' // 林三心
const b = '' || '林三心' // 林三心
const c = false || '林三心' // 林三心
const d = undefined || '林三心' // 林三心
const e = null || '林三心' // 林三心
而??和||最大的区别是,在??这,只有undefined和null才算假值
const a = 0 ?? '林三心' // 0
const b = '' ?? '林三心' // ''
const c = false ?? '林三心' // false
const d = undefined ?? '林三心' // 林三心
const e = null ?? '林三心' // 林三
11、对象计算属性
我们经常碰到这样的问题,无论是在微信小程序还是React中,我们需要根据某个条件去修改某个数据
if (type === 'boy') {
this.setData({
boyName: name
})
} else if (type === 'girl') {
this.setData({
girlName: name
})
}
我也不知道这个新特性叫啥,我就自己取名叫属性动态属性哈哈哈
this.setData({
[`${type}Name`]: name
})
补充
12、Symbol
应用场景1:使用Symbol来作为对象属性名
平常我们对象的属性都是字符串
const obj = {
name: 'Sunshine_Lin',
age: 23
}
console.log(obj['name']) // 'Sunshine_Lin'
console.log(obj['age']) // 23
其实也可以用Symbol来当做属性名
const gender = Symbol('gender')
const obj = {
name: 'Sunshine_Lin',
age: 23,
[gender]: '男'
}
console.log(obj['name']) // 'Sunshine_Lin'
console.log(obj['age']) // 23
console.log(obj[gender]) // 男
但是Symbol作为属性的属性不会被枚举出来,这也是JSON.stringfy(obj)时,Symbol属性会被排除在外的原因
console.log(Object.keys(obj)) // [ 'name', 'age' ]
for(const key in obj) {
console.log(key) // name age
}
console.log(JSON.stringify(obj)) // {"name":"Sunshine_Lin","age":23}
其实想获取Symbol属性也不是没办法。
// 方法一
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(gender) ]
// 方法二
console.log(Reflect.ownKeys(obj)) // [ 'name', 'age', Symbol(gender) ]
应用场景2:使用Symbol来替代常量
有以下场景
// 赋值
const one = 'oneXin'
const two = 'twoXin'
function fun(key) {
switch (key) {
case one:
return 'one'
break;
case two:
return 'two'
break;
}
}
如果变量少的话还好,但是变量多的时候,赋值命名很烦,可以利用Symbol的唯一性
const one = Symbol()
const two = Symbol()
应用场景3:使用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]) // 报错