Skip to content

🚀 方法速查

方法作用详细
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