常见 ES6 语法的简单用法
Sat Apr 02 2022 Posted 3 years ago
本文总结于 2021年12月17日,用法比较偏基础,并没有什么实际的干货,唯一的价值可能就是让我的博客数量 +1~
一、解构赋值 #
<1> 对象和数组
const obj = {
a: 1,
b: 2,
c: 3
}
const { a, b, c } = obj // 等价于 const a = 1; const b = 2; const c = 3;
/********************************/
const arr = [1, 2, 3]
const [a, b, c] = arr // 等价于 const a = 1; const b = 2; const c = 3;
<2> 深度解构
const obj = {
a: 0,
b: {
c: 1
}
}
const { b: { c } } = obj // 等价于 const c = 1 tip: b is not defined
<3> 解构时使用别名
const obj = {
a: 1,
b: 2,
c: 3
}
const { a: count } = obj // 等价于 const count = 1
<5> 变量互换
const a = 1
const b = 2
[b, a] = [a, b]
<5> 解构的对象不能为 undefined
或 null
const {a, b, c} = obj || {}
二、...(拓展运算符) #
const arr1 = [1, 2, 3]
const arr2 = [3, 4, 5, 6]
// const mixArr = [...newSet(arr1.concat(arr2))]
const mixArr = [...new Set([...a, ...b])]
/********************************/
const obj1 = { a: 1 }
const obj2 = { b: 1 }
// const mixObj = Object.assign({}, obj1, obj2)
const mixObj = { ...obj1, ...obj2 }
结合拓展运算符有条件的添加对象的属性:
// 此处可以将 isEmpty 封装为函数
/*
const isEmpty = (field) => this[field] === ''
*/
const isEmpty = this.keyword === ''
const searchCondition = {
...(isEmpty && { keyword: this.keyword }),
}
三、Object.hasOwn #
用于判断对象上是否存在某个属性(需要注意兼容性,最好配合 polyfill 使用)
const person = {
name: 'sehci',
age: 21
}
Object.hasOwn(person, 'name') // true
Object.hasOwn(person, 'gender') // false
// Object.hasOwn 本质上是语法糖,等价于以下代码
Object.prototype.hasOwnProperty.call(person, 'name') // true
四、includes #
includes
是数组上的一个方法,用于判断一个数组是否包含一个指定的值,返回值为 boolean
// bad
if (a === 1 || a === 2 || a === 3 || a === 4) {
// ...
}
// good
if ([1, 2, 3, 4].includes(a)) {
// ...
}
includes
可以接收两个参数: <1> valueToFind
需要查找的元素值 <2> fromIndex
从某个索引开始遍历查找
需要注意的地方是 fromIndex
可以为负数
// arr's length is 3
// fromIndex is -100
// computed index is 3 + (-100) = -97
const arr = [1, 2, 3]
arr.includes('a', -100) // true
arr.includes('a', -2) // false
五、?. (可选链操作符) #
可选链操作符( ?.
)允许读取位于对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
const person = {
name: 'sechi',
age: 21,
cat: {
name: 'kiki'
}
}
// bad
const dogName = person.dog && person.dog.name
// good
const dogName = person.dog?.name
console.log(dogName) // undefined
可选链操作符不仅能用于对象,还可以用于函数的调用
const someInterface = {
someMethod: () => 'call successfully!'
}
const result1 = someInterface.anotherMethod?.() // undefined
const result2 = someInterface.anotherMethod() // someInterface.anotherMethod is not a function
六、??(空值合并运算符) #
空值合并操作符(??
)是一个逻辑操作符,当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。注意:它和逻辑或操作符(||
)不同,逻辑或操作符会在左侧操作数为假值(如false
, 0
, ''
, NaN
)时返回右侧操作数。
const nullValue = null
const emptyString = '' // 空字符串,是一个假值,Boolean("") === false
const num = 42
const valA = nullValue ?? 'valA 的默认值'
const valB = emptyString ?? 'valB 的默认值'
const valC = num ?? 0
console.log(valA) // "valA 的默认值"
console.log(valB) // ""(空字符串虽然是假值,但不是 null 或者 undefined)
console.log(valC) // 42
实际开发中可以用它来简化输入框的非空判断:
// bad
if (value !== null && value !== undefined && value !== '') {
// ...
}
// good
if ((value ?? '') !== '') {
// ...
}
Tip: ??
不可以直接与 &&
和 ||
组合使用,原因是空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的。组合使用时需要使用括号来显式地表明优先级
null || undefined ?? 'foo' // 抛出 SyntaxError
(null || undefined) ?? 'foo' // 返回 "foo"
七、Object.entries / Object.keys / Object.values / Object.fromEntries #
Object.entries / Object.keys / Object.values 这三个方法都可以将对象转换为数组,并且只会遍历自身的属性而不会遍历原型链中的属性。
<1> Object.entries()
方法返回一个给定对象自身可枚举属性的键值对数组。
// 简单示例
const obj = { 0: 'a', 1: 'b', 2: 'c' }
console.log(Object.entries(obj)) // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
// 如果 key 可以被排序,那么遍历的顺序会由 key 决定
const anObj = { 100: 'a', 2: 'b', 7: 'c' }
console.log(Object.entries(anObj)) // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]
// getFoo 并不是 myObj 的可枚举的属性,所以不会被遍历
const myObj = Object.create({}, { getFoo: { value() { return this.foo } } })
myObj.foo = 'bar'
console.log(Object.entries(myObj)) // [ ['foo', 'bar'] ]
// 如果传入的参数类型不是对象,则会被强制转换为对象类型
console.log(Object.entries('foo')) // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
// 如何优雅地迭代键值对~
const obj = { a: 5, b: 7, c: 9 }
for (const [key, value] of Object.entries(obj))
console.log(`${key} ${value}`) // "a 5", "b 7", "c 9"
// 梅开二度
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`) // "a 5", "b 7", "c 9"
})
<2> Object.keys()
方法会返回一个由一个给定对象的自身可枚举属性组成的数组。
// 如果参数为数组,那么会返回由索引组成的数组
const arr = ['a', 'b', 'c']
console.log(Object.keys(arr)) // console: ['0', '1', '2']
// 简单示例
const obj = { 0: 'a', 1: 'b', 2: 'c' }
console.log(Object.keys(obj)) // console: ['0', '1', '2']
// 如果 key 可以被排序,那么遍历的顺序会由 key 决定
const anObj = { 100: 'a', 2: 'b', 7: 'c' }
console.log(Object.keys(anObj)) // console: ['2', '7', '100']
// getFoo 并不是 myObj 的可枚举的属性,所以不会被遍历
const myObj = Object.create({}, {
getFoo: {
value() { return this.foo }
}
})
myObj.foo = 1
console.log(Object.keys(myObj)) // console: ['foo']
<3> Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组。
// 简单示例
const obj = { foo: 'bar', baz: 42 }
console.log(Object.values(obj)) // ['bar', 42]
// 如果 key 可以被排序,那么遍历的顺序会由 key 决定
const an_obj = { 100: 'a', 2: 'b', 7: 'c' }
console.log(Object.values(an_obj)) // ['b', 'c', 'a']
// getFoo 并不是 myObj 的可枚举的属性,所以不会被遍历
const my_obj = Object.create({}, { getFoo: { value() { return this.foo } } })
my_obj.foo = 'bar'
console.log(Object.values(my_obj)) // ['bar']
// 如果传入的参数类型不是对象,则会被强制转换为对象类型
console.log(Object.values('foo')) // ['f', 'o', 'o']
<4> Object.fromEntries()
方法把键值对列表转换为一个对象。执行的操作与 Object.fromEntries
相反
// Map 转化为 Object
const map = new Map([['foo', 'bar'], ['baz', 42]])
const obj = Object.fromEntries(map)
console.log(obj) // { foo: "bar", baz: 42 }
// Array 转化为 Object
const arr = [['0', 'a'], ['1', 'b'], ['2', 'c']]
const obj = Object.fromEntries(arr)
console.log(obj) // { 0: "a", 1: "b", 2: "c" }
// 优雅地用数组方法处理对象~
const object1 = { a: 1, b: 2, c: 3 }
const object2 = Object.fromEntries(
Object.entries(object1)
.map(([key, val]) => [key, val * 2])
)
console.log(object2) // { a: 2, b: 4, c: 6 }