当前位置: 首页 > news >正文

4. 对象新增了哪些扩展?

一、面试开场怎么答更有条理

如果面试官问:

ES6 对对象新增了哪些扩展?

不要直接开始背 API。
更好的答法是先分类:

ES6 对对象的扩展,我一般会从对象写法简化、属性名表达式、方法扩展、对象合并、属性遍历、原型相关能力、Object 新增静态方法这几个方面来回答。
比较常见的有:属性简写、方法简写、计算属性名、Object.is()Object.assign()Object.keys()/values()/entries()、对象的扩展运算符、super__proto__Object.setPrototypeOf()/Object.getPrototypeOf()等。

这样一开口就很像“系统理解”,不是机械背诵。


二、ES6 对对象新增了哪些扩展?


1)属性简写

ES6 允许在对象中,属性名和变量名相同的时候直接简写

ES5 写法

const name = 'Tom' const age = 18 const obj = { name: name, age: age }

ES6 写法

const name = 'Tom' const age = 18 const obj = { name, age }

作用

  • 写法更简洁
  • 语义更清晰
  • 在返回对象、封装数据时非常常用

面试加分点

属性简写本质上是对象字面量语法增强,特别适合在函数返回对象时使用。


2)方法简写

对象中的函数可以简写。

ES5

const obj = { sayHello: function() { console.log('hello') } }

ES6

const obj = { sayHello() { console.log('hello') } }

优点

  • 更接近类方法语法
  • 可读性更强

注意

这种写法定义的是普通函数,不是箭头函数,this依然由调用方式决定。


3)计算属性名

ES6 支持在对象字面量中使用表达式作为属性名。

const key = 'name' const obj = { [key]: 'Tom' } console.log(obj.name) // Tom

更复杂的例子

const index = 1 const obj = { ['item' + index]: 'value' } console.log(obj.item1) // value

场景

  • 动态生成对象 key
  • 表单数据映射
  • 配置对象构建

面试亮点

计算属性名让对象字面量具备了更强的动态表达能力,这在封装配置对象时很常见。


4)Object.is()

作用

用来比较两个值是否严格相等,行为比===更合理一些。

Object.is(1, 1) // true Object.is('a', 'a') // true

它和===的区别

主要区别在两个特殊值上:

+0 === -0 // true Object.is(+0, -0) // false NaN === NaN // false Object.is(NaN, NaN) // true

面试加分说法

Object.is()可以理解为“更精确语义的严格相等比较”,尤其解决了NaN+0/-0的边界问题。


5)Object.assign()

这是 ES6 对对象最重要的扩展之一。

作用

用于将一个或多个源对象的可枚举属性,复制到目标对象上。

const target = { a: 1 } const source = { b: 2 } Object.assign(target, source) console.log(target) // { a: 1, b: 2 }

常见用途

(1)对象合并
const obj = Object.assign({}, { a: 1 }, { b: 2 }) console.log(obj) // { a: 1, b: 2 }
(2)浅拷贝
const obj1 = { a: 1 } const obj2 = Object.assign({}, obj1)
(3)给对象设置默认值
const defaults = { size: 'M', color: 'red' } const config = { color: 'blue' } const result = Object.assign({}, defaults, config) console.log(result) // { size: 'M', color: 'blue' }

注意点:它是浅拷贝

const obj1 = { a: { b: 1 } } const obj2 = Object.assign({}, obj1) obj2.a.b = 2 console.log(obj1.a.b) // 2

面试亮点

Object.assign()很常用,但一定要说明它是浅拷贝,只会拷贝第一层属性,如果属性值是引用类型,复制的是地址。

这句话几乎必说。


6)对象属性的遍历能力增强


Object.keys()

返回对象自身可枚举属性的键名数组。

const obj = { a: 1, b: 2 } console.log(Object.keys(obj)) // ['a', 'b']

Object.values()

返回对象自身可枚举属性的值数组。

const obj = { a: 1, b: 2 } console.log(Object.values(obj)) // [1, 2]

Object.entries()

返回对象自身可枚举属性的键值对数组。

const obj = { a: 1, b: 2 } console.log(Object.entries(obj)) // [['a', 1], ['b', 2]]

常见用途

转 Map
const obj = { a: 1, b: 2 } const map = new Map(Object.entries(obj))
配合for...of
for (const [key, value] of Object.entries(obj)) { console.log(key, value) }

面试加分点

Object.entries()很实用,因为它把对象数据转成了更适合迭代处理的二维数组结构。


7)对象的扩展运算符...

虽然对象展开在更严格分类里通常归到 ES2018,但前端面试里经常会和 ES6 一起问,你可以主动说明。

对象合并

const a = { x: 1 } const b = { y: 2 } const c = { ...a, ...b } console.log(c) // { x: 1, y: 2 }

对象拷贝

const obj1 = { a: 1 } const obj2 = { ...obj1 }

覆盖属性

const obj = { a: 1, b: 2, ...{ b: 3 } } console.log(obj) // { a: 1, b: 3 }

面试中怎么说更严谨?

对象扩展运算符非常常用,但它严格来说不是 ES6,而是后续版本加入的。不过工程里常和Object.assign()一起用于对象浅拷贝和合并。

这样说会显得你很严谨。


8)__proto__与原型操作方法

ES6 明确了获取和设置原型的一些方式。


Object.getPrototypeOf()

获取对象原型

const obj = {} console.log(Object.getPrototypeOf(obj) === Object.prototype) // true

Object.setPrototypeOf()

设置对象原型

const proto = { say() { console.log('hello') } } const obj = {} Object.setPrototypeOf(obj, proto) obj.say() // hello

__proto__

const obj = {} console.log(obj.__proto__ === Object.prototype) // true

不过一般不推荐在生产中频繁直接操作__proto__,因为可读性和性能都不理想。

面试加分说法

ES6 之后更推荐通过Object.getPrototypeOf()Object.setPrototypeOf()操作原型,而不是直接依赖__proto__


9)对象方法中的super

ES6 允许在对象的方法中使用super,指向当前对象的原型对象。

const proto = { foo() { console.log('proto foo') } } const obj = { foo() { super.foo() } } Object.setPrototypeOf(obj, proto) obj.foo() // proto foo

注意

super只能在对象的简写方法中使用,不能在普通函数属性中随便用。

面试亮点

对象中的super本质上是对原型方法的引用能力增强,它让对象字面量的方法也具备了类似类继承中的调用上层方法能力。


10)属性的可枚举性变化与遍历顺序

这个属于进阶内容,能讲出来会显得很强。

ES6 对对象属性遍历顺序做了更明确的规则:

  1. 先遍历整数属性名,按升序
  2. 再遍历字符串属性名,按加入顺序
  3. 最后遍历 Symbol 属性名,按加入顺序

示例

const obj = { 2: 'b', 1: 'a', c: 'c', b: 'b' } console.log(Object.keys(obj)) // ['1', '2', 'c', 'b']

这个属于高级回答,可选补充。


三、面试怎么回答更精彩?

你不能只说“新增了哪些 API”,要再说一句“为什么这些扩展重要”。

可以这样总结:

我觉得 ES6 对对象的扩展,本质上做了三件事:
第一,让对象字面量写法更简洁,比如属性简写、方法简写、计算属性名;
第二,让对象的拷贝、合并和遍历更方便,比如Object.assign()Object.keys()Object.values()Object.entries()
第三,让对象更好地融入原型和面向对象能力,比如superObject.getPrototypeOf()Object.setPrototypeOf()
所以它不只是加了几个 API,而是整体提升了对象在工程中的表达能力。

这段是很加分的总结。


四、标准版面试回答

ES6 对对象主要新增了几类扩展。

第一类是对象字面量增强,比如属性简写、方法简写和计算属性名。它们让对象定义更简洁,也更适合动态构建对象。

第二类是对象静态方法增强,比如Object.is()Object.assign()Object.is()提供了比===更合理的值比较方式,而Object.assign()常用于对象合并和浅拷贝,但要注意它只能做浅拷贝。

第三类是对象遍历能力增强,比如Object.keys()Object.values()Object.entries(),尤其Object.entries()很适合配合for...of或转换成Map使用。

第四类是原型和继承相关的增强,比如Object.getPrototypeOf()Object.setPrototypeOf(),以及对象方法中的super,这些都让对象的原型操作更明确。

另外在实际开发中,对象扩展运算符...也经常和这些内容一起使用,虽然它严格来说属于后续版本,但工程里常用于对象的浅拷贝和合并。

如果从整体上看,我觉得 ES6 对对象的扩展,核心是让对象写法更简洁、遍历更方便、原型操作更规范。


五、如果想答得更高级,可以补充这些点


1)Object.assign()和对象展开运算符的共同点

  • 都常用于对象合并
  • 都是浅拷贝
  • 后面的属性会覆盖前面的属性

2)Object.is()===的区别

重点记住两点:

  • NaN
  • +0/-0

3)对象字面量方法简写不是箭头函数

这点很多人会混淆,主动提一下很加分。


4)Object.entries()很适合和Map配合

说明你知道它的实际应用价值。


六、对比总结表

扩展作用说明
属性简写{name}属性名和值名相同时简写
方法简写foo() {}对象方法定义更简洁
计算属性名[key]: value支持动态属性名
Object.is()更精确的值比较区分+0/-0,识别NaN
Object.assign()对象合并/浅拷贝只拷贝一层
Object.keys()获取键名数组可枚举属性
Object.values()获取值数组可枚举属性
Object.entries()获取键值对数组方便遍历、转Map
Object.getPrototypeOf()获取原型原型操作更规范
Object.setPrototypeOf()设置原型不建议频繁使用
super调用原型上的方法用于对象简写方法中
...对象展开严格来说是后续版本

七、精简版面试回答

如果想短一点,可以这样说:

ES6 对对象的扩展主要有三类:
一是对象字面量增强,比如属性简写、方法简写和计算属性名;
二是静态方法增强,比如Object.is()Object.assign(),其中Object.assign()常用于对象合并和浅拷贝;
三是遍历和原型能力增强,比如Object.keys()Object.values()Object.entries(),以及Object.getPrototypeOf()Object.setPrototypeOf()和对象方法中的super

如果从工程角度看,这些扩展主要让对象的定义更简洁、遍历更方便、合并和原型操作更规范。


八、一句话总结

面试官真正想听的是:

  • 你是否知道ES6 对对象新增了哪些能力
  • 你能不能按分类进行表达
  • 你是否理解这些扩展在实际开发中的价值
  • 你会不会主动指出像对象展开运算符这类内容的版本边界
http://www.cnnetsun.cn/news/1774073.html

相关文章:

  • 嵌入式学习笔记——认识STM32的 GPIO口
  • GPT-5.2三兄弟怎么选?Instant/Thinking/Pro保姆级对比,附Python/Node.js接入避坑指南
  • 2026年4月OpenClaw(Clawdbot)如何集成?华为云新手攻略:搭建及大模型API、Skill配置指南
  • Chatblade终极指南:10个技巧让你成为ChatGPT CLI高手
  • 2026年4月OpenClaw(Clawdbot)如何搭建?京东云快速流程:部署与大模型API、Skill集成指南
  • 实战避坑指南:用一颗12V/50A的eFuse(比如MP5991)给大功率板卡供电,我的PCB布局踩了哪些雷?
  • Lit-LLaMA与LitGPT终极对比:如何选择最适合你的大语言模型方案
  • OpenClaw健康检查:千问3.5-9B服务状态监控与告警
  • 达梦数据库图形化安装界面常见报错及解决方案
  • 算法工具箱之前缀和
  • NeMo Guardrails CLI工具终极指南:从调试到部署的完整教程
  • Spring Boot 4.3 新特性:构建更智能的 Java 应用
  • 浏览器神器Tampermonkey:手把手教你安装和使用4款必备油猴脚本
  • Sequel批量插入性能终极指南:如何快速处理百万级数据
  • MovieGuide依赖注入教程:Dagger 2在Android项目中的终极指南
  • OpenClaw+Kimi-VL-A3B-Thinking成本对比:自建多模态服务vs商用API
  • OpenClaw+Kimi-VL-A3B-Thinking成本对比:自建vs云API哪种更划算
  • Embree错误处理与调试:常见问题排查与解决方案
  • 终极指南:如何为Tech-Interview-Cheat-Sheet开源项目贡献代码
  • 从“找茬”到“预防”:AI如何预测代码中的潜在Bug
  • C++实现字符串转整数(atoi)详解
  • OpenClaw安全实践:Qwen3.5-9B本地化处理敏感数据
  • Phi-4-mini-reasoning开发者指南:日志排查、健康检查与服务重启实操
  • 告别卡顿!香橙派PC刷入Ubuntu 22.04 LTS,保姆级从烧录到EMMC迁移全流程
  • Globby最佳实践:避免常见陷阱的7个技巧
  • 基于ESP32S3芯片的机器人控制器设计与实现
  • # 发散创新:基于事件驱动架构的实时日志监控系统设计与实现在现代分布式系统中,**事件驱动编程模型**正
  • OpenClaw开源贡献:为Qwen3.5-9B-AWQ-4bit编写自定义技能指南
  • RockyLinux 8.6安装与Linux核心命令掌握(2/2)
  • 1.4 编译与烧录第一个例程(Hello World + Blinky)