ES6 - 对象 - 快速梳理

15 阅读2分钟

对象的扩展

豆包.png

值的简写

// 变量简写
const name = '张三'
const obj = { name } // 等同于 { name : name }
console.log(obj) // { name : '张三'}

// 函数简写
const obj = {
  methodName() {}, // 等同于 methodName: function () {},
}

场景延伸

// vue3 子组件暴露方法
defineExpose({ method1, method2 })

名的动态

const name = 'firstName'
// 用 [] 表达式来动态声明属性名
const obj = {
  [name]: '张三',
  ['method' + 'One']() {
    return this[name]
  },
}
console.log(obj['method' + 'One']()) // 张三

对象下函数的名字

// 与函数的扩展相同,有 name 属性
const obj = {
  fnName() {},
}
console.log(obj.fnName.name) // fnName

对象的枚举与遍历

枚举:ES6 新增规定,所有 Class 的原型的方法都是不可枚举

Object.getOwnPropertyDescriptor(
  class {
    foo() {}
  }.prototype,
  'foo'
).enumerable
// false

遍历:新增遍历对象的方法

// 示例中含有:自身属性、继承属性、Symbol属性、不可枚举属性

// 根据打印结果,观察能够遍历哪种类型的数据
const obj = {
  a: '自身属性',
  [Symbol('b')]: 'Symbol属性',
  __proto__: { c: '继承属性' },
}
Object.defineProperty(obj, 'd', {
  value: '不可枚举属性',
  enumerable: false,
})

// ES6 前的 for...in  (自、继)
for (let item in obj) {
  console.log(item) // a c
}

// Object.keys()、Object.values()、Object.entries()
console.log(Object.keys(obj)) // [ "a" ]
console.log(Object.values(obj)) // [ "自身属性" ]
console.log(Object.entries(obj)) // [["a","自身属性"]]

// Object.getOwnPropertyNames() (自、不可枚举)
console.log(Object.getOwnPropertyNames(obj)) // [ "a", "d" ]

// Object.getOwnPropertySymbols() (Symbol)
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol("b") ]

// Reflect.ownKeys() (自、不可枚举、Symbol)
console.log(Reflect.ownKeys(obj)) // [ "a", "d", Symbol("b") ]

总结:

  1. 仅 for...in 能遍历继承属性,其他都不能
  2. 其他遍历逐步升级可分为
  • 自身
  • 自身 + 不可枚举
  • 自身 + 不可枚举 + Symbol
  • Symbol

分别对应:

  • Object.keys()
  • Object.getOwnPropertyNames()
  • Reflect.ownKeys()
  • Object.getOwnPropertySymbols()

super 关键字

// 函数内 super 关键字指向函数所在对象的原型对象
const obj = {
  name: '自己的名字',
  // 只能再函数内部,且用这种简写方式声明的函数才能用 super
  getName() {
    return super.name
  },
}
Object.setPrototypeOf(obj, { name: '继承的名字' })
console.log(obj.getName()) // 继承的名字

对象的扩展运算符(ES2018)

// 解构赋值
const obj = { a: 1, b: 2, c: 3 }
const { a, ...obj2 } = obj
console.log(obj2) // { b: 2, c: 3}

// 合并对象
const obj = { a: 1, b: 2 }
const obj1 = { ...obj, c: 3 }
console.log(obj1) //  { a: 1, b: 2, c: 3 }

// 复制对象
const obj = { a: 1 }
const copyObj = { ...obj }
console.log(copyObj) // { a: 1 }
// 注:复制是浅拷贝。涉及类、原型的复制详情见文档
// https://es6.ruanyifeng.com/#docs/object#%E6%89%A9%E5%B1%95%E8%BF%90%E7%AE%97%E7%AC%A6

AggregateError 错误对象(ES2021)

// 同步抛出多个错误,适用于 Promise.any() 多个接口报错的情况
try {
  // 参数1: 所有抛出的错误;参数2: 所有错误的提示文字
  throw new AggregateError(
    [new Error('some error1'), new Error('some error2')],
    'Hello'
  )
} catch (e) {
  console.log(e instanceof AggregateError) // true
  console.log(e.message) // "Hello"
  console.log(e.name) // "AggregateError"
  console.log(e.errors) // [ Error: "some error1", Error: "some error2" ]
}

Error 对象的 cause 属性(ES2022)

// 添加报错原因的描述
const actual = new Error('an error!', { cause: 'Error cause' })
actual.cause // 'Error cause'