Skip to content

对象的扩展

ES6 大幅增强了对象字面量的语法,让对象的创建更加简洁。

属性简写#

当属性名和变量名相同时,可以简写:

const name = '张三'
const age = 25
// ES5
const user1 = {
name: name,
age: age,
}
// ES6 简写
const user2 = { name, age }
console.log(user2) // { name: '张三', age: 25 }

实际应用#

// 函数返回值
function getUser() {
const id = 1
const name = '张三'
const email = 'test@test.com'
return { id, name, email }
}
// 模块导出
const API_URL = 'https://api.example.com'
const timeout = 5000
export { API_URL, timeout }
// 解构后重新组装
const { id, name, ...rest } = fullUser
const publicUser = { id, name }

方法简写#

对象方法可以省略 function 关键字:

// ES5
const obj1 = {
sayHello: function () {
console.log('Hello')
},
}
// ES6 简写
const obj2 = {
sayHello() {
console.log('Hello')
},
// Generator 方法
*createIterator() {
yield 1
yield 2
},
// 异步方法
async fetchData() {
return await fetch('/api/data')
},
}

🔶 方法简写不能作为构造函数#

const obj = {
// 方法简写
method() {},
// 传统方法
traditional: function () {},
}
// new obj.method(); // TypeError: obj.method is not a constructor
new obj.traditional() // OK(但不推荐这样用)

计算属性名#

属性名可以是表达式:

const key = 'name'
const prefix = 'user_'
const obj = {
[key]: '张三',
[`${prefix}id`]: 1,
['say' + 'Hello']() {
console.log('Hello')
},
}
console.log(obj.name) // '张三'
console.log(obj.user_id) // 1
obj.sayHello() // 'Hello'

实际应用#

// 动态创建对象
function createObject(key, value) {
return { [key]: value }
}
createObject('name', '张三') // { name: '张三' }
// 以 Symbol 为键
const ID = Symbol('id')
const obj = {
[ID]: 123,
name: '张三',
}
// 根据条件创建属性
const type = 'error'
const log = {
message: 'Something went wrong',
[`${type}Code`]: 500,
[`is${type.charAt(0).toUpperCase() + type.slice(1)}`]: true,
}
// { message: '...', errorCode: 500, isError: true }

属性名表达式与简写不能同时使用#

const key = 'name'
const name = '张三'
// 🔶 错误
// const obj = { [key] }; // SyntaxError
// 正确
const obj = { [key]: name } // { name: '张三' }

方法的 name 属性#

函数有 name 属性,对象方法也有:

const obj = {
sayHello() {},
get name() {
return '张三'
},
set name(value) {},
}
obj.sayHello.name // 'sayHello'
// getter/setter 的 name 需要通过描述符获取
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name')
descriptor.get.name // 'get name'
descriptor.set.name // 'set name'

特殊情况:

// bind 创建的函数
function foo() {}
foo.bind({}).name // 'bound foo'
// 匿名函数
;(function () {}).name // ''
// Symbol 键的方法
const sym = Symbol('description')
const obj = { [sym]() {} }
obj[sym].name // '[description]'

super 关键字#

super 在对象方法中指向原型对象:

const parent = {
greet() {
return 'Hello from parent'
},
}
const child = {
__proto__: parent,
greet() {
// super 指向原型对象 parent
return super.greet() + ' and child'
},
}
child.greet() // 'Hello from parent and child'

🔶 super 只能用在对象方法简写中:

const obj = {
// ✅ 方法简写中可以使用 super
method() {
super.foo()
},
// ❌ 传统方法中不能使用
traditional: function () {
// super.foo(); // SyntaxError
},
// ❌ 箭头函数中不能使用
arrow: () => {
// super.foo(); // SyntaxError
},
}

实际应用#

// 混入模式
const Serializable = {
toJSON() {
return JSON.stringify(this)
},
}
const user = {
__proto__: Serializable,
name: '张三',
age: 25,
toJSON() {
// 调用父类方法,但排除敏感信息
const { password, ...safe } = this
return JSON.stringify(safe)
},
}
// 方法覆盖与调用
const base = {
init() {
console.log('Base init')
},
}
const extended = {
__proto__: base,
init() {
super.init() // 先调用父类
console.log('Extended init')
},
}
extended.init()
// 'Base init'
// 'Extended init'

对象扩展运算符#

ES2018 允许在对象中使用扩展运算符:

// 复制对象
const original = { a: 1, b: 2 }
const copy = { ...original }
// 合并对象
const obj1 = { a: 1, b: 2 }
const obj2 = { c: 3, d: 4 }
const merged = { ...obj1, ...obj2 } // { a: 1, b: 2, c: 3, d: 4 }
// 覆盖属性
const defaults = { theme: 'light', lang: 'en' }
const settings = { ...defaults, lang: 'zh' } // { theme: 'light', lang: 'zh' }
// 条件属性
const isDev = true
const config = {
api: '/api',
...(isDev && { debug: true }),
}

解构与简写结合#

// 提取并重命名
const response = {
data: { user: { name: '张三', age: 25 } },
status: 200,
}
const {
data: {
user: { name, age },
},
status,
} = response
const result = { name, age, status }
// { name: '张三', age: 25, status: 200 }
// 函数参数解构 + 返回简写
function processUser({ name, age, email }) {
// 处理逻辑...
const processed = true
return { name, age, email, processed }
}

实战应用#

配置对象#

function createServer(options = {}) {
const { port = 3000, host = 'localhost', https = false } = options
// 使用简写返回配置
return { port, host, https }
}

状态更新#

function reducer(state, action) {
switch (action.type) {
case 'SET_NAME':
return { ...state, name: action.payload }
case 'SET_AGE':
return { ...state, age: action.payload }
case 'RESET':
return { ...initialState }
default:
return state
}
}

动态表单#

function handleChange(event) {
const { name, value } = event.target
setFormData((prev) => ({
...prev,
[name]: value,
}))
}

API 响应处理#

async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
const { data: user, meta } = await response.json()
return {
...user,
fetchedAt: new Date(),
...meta,
}
}

小结#

特性语法说明
属性简写{ name }变量名与属性名相同时
方法简写{ method() {} }省略 function 关键字
计算属性名{ [expr]: value }属性名可以是表达式
supersuper.method()访问原型对象(仅方法简写中)
扩展运算符{ ...obj }复制/合并对象

这些增强让对象字面量更加强大和灵活,是日常开发中最常用的语法糖。