🚀 方法速查
方法 | 作用 | 详细 |
---|---|---|
Object.defineProperty | 定义对象的数据属性或访问器属性 | 示例:使用 Object defineProperty 定义单个数据属性 示例:使用 Object defineProperty 定义单个访问器属性 |
Object.defineProperties | 定义对象的多个数据属性或访问器属性 | 示例:使用 Object defineProperties 定义多个属性 |
Object.getOwnPropertyDescriptor(属性所在的对象, '属性名') | 获取指定属性的属性描述符(内部特性) | 读取属性的内部特性 |
Object.getOwnPropertyDescriptors(对象) | 获取对象所有自有属性的属性描述符(内部特性) | 读取属性的内部特性 |
Object.assign(目标对象,源对象) | 合并对象 | 对象合并 |
Object.is(obj1,obj2) | 比较两个对象是否相等 | 对象相等判定 |
对象的内部特性
对象的内部特性用于描述属性的特征,不能用js直接访问。内部特性使用双中括号括起来以便区分
数据属性
数据属性包含一个保存数据值的位置,它有4个特性。可以直接定义,此时[[enumerable]]
,[[writable]]
,[[configurable]]
均会被设置为true
js
const Elysia = { name: "爱莉希雅" }
数据属性的内部特性 | 说明 | 默认值 |
---|---|---|
[[Configurable]] | 表示属性是否可用delete删除并重新定义,是否可更改其内部特性。该内部特性配置后无法再次配置 | true |
[[Enumerable]] | 表示属性是否可被for-in循环返回(枚举) | true |
[[Writable]] | 表示属性是否可被修改 | true |
[[Value]] | 属性的值 | undefined |
示例:使用Object.defineProperty
定义单个数据属性
注意:`Object.defineProperty` 定义属性时,**未定义的属性默认都为 false**
js
let Elysia = {}
Object.defineProperty(Elysia, 'name', {
configurable: true,
enumerable: true,
writable: false,
value: '爱莉希雅'
})
访问器属性
访问器属性不包含数据值,它有4个特性。只能通过Object.defineProperty
定义。 访问器属性不一定都要定义,只定义get会导致属性是只读的,无法修改。只定义set会导致属性无法读取
访问器属性的内部特性 | 说明 | 默认值 |
---|---|---|
[[Configurable]] | 表示属性是否可用delete删除并重新定义,是否可更改其内部特性,或者将其改为数据属性。该内部特性配置后无法再次配置 | true |
[[Enumerable]] | 表示属性是否可被for-in循环返回(枚举) | true |
[[Get]] | 读取属性时调用 | undefined |
[[Set]] | 设置属性时调用 | undefined |
示例:使用Object.defineProperty
定义单个访问器属性
注意:`Object.defineProperty`定义属性时,**未定义的属性默认都为false**
js
const Elysia = {
name: '爱莉希雅',
age: 20
}
Object.defineProperty(Elysia, 'trueAge', {
get () {
return this.age - 2
}
})
Object.defineProperty(Elysia, 'status', {
get () {
return this.name
},
set (value) {
this.name = `[TRUE]${value}`
}
})
console.log(Elysia.trueAge)// 18
console.log(Elysia.status)// 爱莉希雅
Elysia.status = '爱莉希雅'
console.log(Elysia.name)//[TRUE]爱莉希雅
示例:使用Object.defineProperties
定义多个属性
注意:`Object.defineProperties` 定义属性时,**未定义的属性默认都为 false**
js
const Elysia = {}
Object.defineProperties(Elysia, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: '爱莉希雅'
},
age: {
configurable: true,
enumerable: true,
writable: true,
value: '18'
},
status:{
get () {
return this.name
},
set (value) {
this.name = `[TRUE]${value}`
}
}
})
读取属性的内部特性
方法 | 说明 |
---|---|
Object.getOwnPropertyDescriptor(属性所在的对象, '属性名') | 获取指定属性的属性描述符(内部特性) |
Object.getOwnPropertyDescriptors(对象) | 获取对象所有自有属性的属性描述符(内部特性) |
对象合并
Object.assign(目标对象,源对象)
多个源对象用逗号隔开 如果多个对象都有相同的属性,则会使用最后一个复制过来的值 合并时访问器属性将会作为静态值合并 浅复制,只会复制对象的引用 无法回滚更改,合并失败会报错但不会回滚更改,使用try catch时要格外注意
相等判定
Object.is
js
Object.is(NaN, NaN)//true
Object.is(true, 1)//false
Object.is({}, {})//false
Object.is(2, '2')//false
增强的对象语法
1. 属性值简写
js
// 原写法
let userName = 'aa'
let person = {
userName:userName
}
js
//简写
let userName = 'aa'
let person = {
userName
}
2. 可计算属性
js
//原写法,不能在字面量中动态命名属性,只能先声明对象后,再使用中括号添加属性
const userName = 'name'
const person = {}
person[userName] = 'Elysia'
console.log(person)//{ name: 'Elysia' }
js
//新写法,直接在对象字面量中动态属性赋值
const userName = 'name'
const person = {
[userName]: 'Elysia'
}
console.log(person)//{ name: 'Elysia' }
中括号包围的对象键会被当做JS表达式,故可以使用复杂的表达式
⚠️ 注意: 可计算属性表达式如果抛出错误,不会回滚更改
js
const userName = 'name'
function changeKey (key) {
return key + '1'
}
const person = {
[changeKey(userName)]: 'Elysia'
}
console.log(person){ name1: 'Elysia' }
3. 简写方法名(略)
对象解构
对象解构
js
// 不使用对象解构
const Elysia = {
name: '爱莉希雅',
age: 18
}
const name = Elysia.name
const age = Elysia.age
console.log(name, age);//爱莉希雅 18
js
// 使用对象解构。对象不存在的属性会赋值为undefined,可以在解构中定义默认值解决该问题
// 解构的变量和对象属性名一致时,可以简写
const Elysia = {
name: '爱莉希雅',
age: 18
}
const { name: trueName, age, gender, like = 'everyone' } = Elysia
console.log(trueName, age, gender, like);//爱莉希雅 18 undefined everyone
js
// 给事先已经声明的变量赋值,需要将赋值表达式放在一对括号中
let trueName = '';
const Elysia = { name: '爱莉希雅' };
({ name: trueName } = Elysia); // 给事先已经声明的变量赋值,需要将赋值表达式放在一堆括号中
console.log(trueName);//爱莉希雅
js
// 嵌套解构
let Elysia = { name: '爱莉希雅', job: { title: 'people' } };
let ElysiaCopy = {};
({ name: ElysiaCopy.trueName, job: ElysiaCopy.job } = Elysia);
Elysia.name = 'error'//这里跟下面不一样哦
Elysia.job.title = 'none'//因为解构时复制的是对象的引用,所以这里修改源对象,目标对象也会被修改
console.log(ElysiaCopy);//{ trueName: '爱莉希雅', job: { title: 'none' } }
部分解构
如果解构时出错,则解构赋值只会完成一部分。使用try catch时,错误之前的解构赋值会完成,错误之后的解构赋值均不成功
在函数参数中使用(参数上下文匹配)
在函数的参数列表中也可以进行解构赋值,并且不会影响argument对象
js
const Elysia = {
name: '爱莉希雅',
age: 18
}
function pringPeople ({ name: trueName, age }) {
console.log(trueName, age)
}
pringPeople(Elysia)//爱莉希雅 18