ES6 对象特性详解:语法扩展、Object 方法及解构赋值
本文深入解析 ES6 中对象的新增功能,涵盖字面量语法的简化与计算属性、Object.is 对全等运算符的补充、Object.assign 实现混合模式及访问器属性的处理限制,以及 Object.setPrototypeOf 和 Super 关键字对原型链操作的增强。同时详细讲解对象解构赋值的默认值、非同名变量及嵌套解构用法,并介绍普通、特异、标准与内建对象的分类定义。
ES6 对象特性概览
ES6通过字面量语法扩展、新增方法及原型改进强化对象功能,并利用解构赋值简化数据提取。
字面量语法扩展
一、字面量语法扩展
ES6下对象字面量创建更简洁,支持属性简写与可计算属性名。方法定义无需冒号和function关键字,示例如下:
// Demo1
var value = "name", age = 18
var person = {
age, // age: age
['my' + value]: 'Jenny', // myname
sayName () { // sayName: function()
console.log(this.myname)
}
}
console.log(person.age) // 18
console.log(person.myname) // Jenny
person.sayName(); // Jenny
ES6移除了ES5严格模式下的重复属性检查机制,无论何种模式,同名属性均取最后一个值。
// demo2
var person = {
['my' + value]: 'Jenny',
myname: 'Tom',
myname: 'Lee',
}
console.log(person.myname) // Lee
Object 新增方法详解
二、新增方法
自ES5起的设计目标为:避免创建新的全局函数,也不在Object.prototype上添加新方法。
为简化特定任务,ES6在Object对象上引入若干新方法。
Object.is() 严格相等判断
2.1 Object.is( )
ES6引入Object.is()以弥补全等运算符在特定计算上的不准确。
全等运算符不触发类型强制转换,Object.is()结果类似,但对+0与-0(JS引擎中视为不同实体)及NaN的比较结果不同,示例如下:
// demo3
console.log(5 == '5') // true
console.log(5 === '5') // false
console.log(Object.is(5, '5')) // false
console.log(+0 == -0) // true
console.log(+0 === -0) // true
console.log(Object.is(+0, -0)) // false
console.log(NaN == NaN) // false
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true
Object.is()对所有值执行更严格的等价判断。是否用其替代全等操作符(===)取决于这些特殊情况是否影响代码逻辑。
Object.assign() 混合模式与限制
2.2 Object.assign( )
ES6添加Object.assign()以支持混合(Mixin)模式,即对象接收另一对象的属性和方法。注意是接收而非继承,例如接收demo1中的对象:
// demo4
var friend = {}
Object.assign(friend, person)
friend.sayName() // Jenny
console.log(friend.age) // 18
console.log(Object.getPrototypeOf(friend) === person) // false
在Object.assign()出现前,许多JS库通过自定义mixin()方法实现对象组合,代码类似:
function mixin(receiver, supplier) {
Object.keys(supplier).forEach(function (key) {
receiver[key] = supplier[key]
})
return receiver
}
mixin()方法使用“=”赋值操作,无法复制访问器属性。同理,Object.assign()仅执行赋值,访问器属性在接收对象中转变为数据属性。示例如下:
// demo5
var animal = {
name: 'lili',
get type () {
return this.name + type
},
set type (news) {
type = news
}
}
animal.type = 'cat'
console.log(animal.type) // lilicat
var pet = {}
Object.assign(pet, animal)
console.log(animal) // { name: 'lili', type: [Getter/Setter] }
console.log(pet) // { name: 'lili', type: 'lilicat' }
Object.setPrototypeOf() 原型修改
2.3 Object.setPrototypeOf( )
通过构造函数或Object.create()创建对象时,原型通常已指定。ES6新增Object.setPrototypeOf()方法以改变对象原型。
例如创建继承person的coder对象,随后改变coder的原型:
// demo6
let person = {
myname: 'Jenny',
sayName () {
console.log(this.myname)
}
}
// 创建原型为 person 的 coder 对象
let coder = Object.create(person)
coder.sayName() // Jenny
console.log(Object.getPrototypeOf(coder) === person) // true
let hero = {
myname: 'lee',
sayName () {
console.log(this.myname)
}
}
// 改变 coder 对象的原型为 hero
Object.setPrototypeOf(coder, hero)
coder.sayName() // lee
console.log(Object.getPrototypeOf(coder) === hero) // true
对象原型存储于内部专有属性[[Prototype]]。Object.getPrototypeOf()返回该值,Object.setPrototypeOf()修改其值。此方法强化了对原型的操作,下一节重点讲解其他原型操作方式。
对象原型的增强与 Super 关键字
三、增强对象原型
原型是JS继承的基础。ES6针对原型进行多项改进,旨在更灵活地使用原型。除新增的Object.setPrototypeOf()外,还引入Super关键字简化原型访问。
Super 关键字的使用与限制
3.1 Super关键字
ES6引入Super以便捷访问对象原型。上一节介绍ES5可使用Object.getPrototypeOf()返回原型。举例说明Super的便捷性,当对象需复用原型方法并重新定义自身方法时,两种实现方式如下:
// demo7
let coder1 = {
getName () {
console.log("coder1 name: ")
Object.getPrototypeOf(this).sayName.call(this)
}
}
// 设置 coder1 对象的原型为 hero(demo6)
Object.setPrototypeOf(coder1, hero)
coder1.getName() // coder1 name: lee
let coder2 = {
getName () {
console.log("coder2 name: ")
super.sayName()
}
}
Object.setPrototypeOf(coder2, hero)
coder2.getName() // coder2 name: lee
在coder1对象的getName方法中,需调用call(this)以确保使用原型方法的this,实现较复杂且多重继承时易导致递归调用栈溢出。直接使用Super则简单且安全。
注意必须在简写方法中使用Super,否则报错。例如以下代码运行语法错误:
let coder4= {
getName: function () { // getName () 正确
super.sayName() // SyntaxError: 'super' keyword unexpected here
}
在示例中,getName成为由匿名function定义的属性,在当前上下文中调用Super引用属非法操作。若不理解,可进一步查看方法的从属对象。
方法的从属对象 [[HomeObject]]
3.2 方法的从属对象
ES6之前,“方法”是具功能而非数据的对象属性。ES6正式将方法定义为具有[[HomeObject]]内部属性的函数。
[[HomeObject]]属性存储当前方法的从属对象,例如:
let coder5 = {
sayName () {
console.log("I have HomeObject")
}
}
function shareName () {
console.log("No HomeObject")
}
coder5对象的sayName()方法的[[HomeObject]]属性值为coder5。而function定义的shareName()未将其赋值给对象,故未定义其[[HomeObject]]属性,这在使用Super时至关重要。
Super通过在[[HomeObject]]属性上调用Object.getPrototypeOf()获取原型引用,搜索原型得到同名函数,最后设置this绑定以调用相应方法。
解构赋值技术
四、解构赋值
ES6为数组和对象字面量提供解构新特性,可简化数据提取过程,减少同质化代码。解构的基本语法示例如下:
let user = {
name: 'jenny',
id: 18
}
let {name, id} = user
console.log(name, id) // jenny 18
注意在这段代码中,user.name存储在与对象属性名同名的name变量中。
解构默认值处理
4.1 默认值
若解构时变量名与对象属性名不同(即对象中不存在),该变量默认值为undefined:
let user = {
name: 'jenny',
id: 18
}
let {name, id, job} = user
console.log(name, id, job) // jenny 18 undefined
非同名变量赋值语法
4.2 非同名变量赋值
非同名变量的默认值为undefined,但更多时候需为其赋值,并将对象属性值赋给非同名变量。ES6为此提供扩展语法,与对象字面量属性初始化程序相似:
let user = {
name: 'jenny',
id: 18
}
let {name, id = 16, job = 'engineer'} = user
console.log(name, id, job) // jenny 18 engineer
let {name: localName, id: localId} = user
console.log(localName, localId) // jenny 18
let {name: otherName = 'lee', job: otherJob = 'teacher'} = user
console.log(otherName, otherJob) // jenny teacher
此语法实际与对象字面量相反,赋值名在冒号左侧,变量名在右侧。解构赋值时仅更新默认值,不能覆盖对象原有的属性值。
嵌套对象解构
4.3 嵌套解构
解构嵌套对象的语法仍类似对象字面量,使用花括号继续查找下层结构:
let user = {
name: 'jenny',
id: 18,
desc: {
pos: {
lng: 111,
lat: 333
}
}
}
let {desc: {pos}} = user
console.log(pos) // { lng: 111, lat: 333 }
let {desc: {pos: {lng}}} = user
console.log(lng) // 111
let {desc: {pos: {lng: longitude}}} = user
console.log(longitude) // 111
ES6 对象分类定义
五、对象类别
ES6规范定义了对象的类别,特别是针对浏览器等执行环境。
- 普通(Ordinary)对象
具备JS对象所有的默认内部行为
- 特异(Exotic)对象
具备某些与默认行为不符的内部行为
- 标准(Standard)对象
ES6规范中定义的对象 可以是普通对象或特异对象,例如Date、Array等
- 内建对象
脚本开始执行时存在于JS执行环境中的对象 所有标准对象都是内建对象
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
