JavaScript Object 对象-数据类型

Object.create()

1Object.create(prototype, [descriptors])
  • 返回一个新对象
  • 新对象的proto指向第一个参数。参数可以为 null,即没有原型对象
  • 要添加的属性以及配置
1const newObj = Object.create(obj, {
2  sex: {
3    // 键名
4    value: '男', // 键值,默认 undefined
5    writable: true, // 是否可以被修改。默认 false
6    configurable: true, // 是否可以被删除。默认 false
7    enumerable: true, // 是否支持可枚举(for in 访问)。默认值是 false
8  },
9})

Object.defineProperty()

1Object.defineProperty(obj, [propName], descriptor)
  • 直接操作参数 1 obj 地址
  • propName: 添加的键名[两个参数时 = 配置选项的 value 值]
  • descriptor: 配置选项
1const obj = { sex1: '' }
2
3Object.defineProperties(obj, {
4  sex: {
5    // 也可以有 Object.create() 的配置
6    set(value) {
7      // 赋值时调用
8      this.sex1 = value
9    },
10    get() {
11      // 获取值时调用
12      return this.sex1
13    },
14  },
15})
  1. 可以多次调用 Object.defineProperty() 方法修改同一个属性,但把 configurable 设置为 false 之后就会报错。
  2. 当使用了 getter 或 setter 方法,不允许使用 writable 和 value 这两个属性。如果使用,会直接报错

Object.defineProperties()

Object.defineProperties(obj, props)

  • obj:要修改的对象
  • props:属性值
1const obj = {}
2Object.defineProperties(obj, {
3  property1: {
4    value: true,
5    writable: true,
6  },
7  property2: {
8    value: 'Hello',
9    writable: false,
10  },
11})

Object.assign()

1Object.assign(target, ...sources)
  • 后面的 sources 源对象 拷贝到 target 目标对象上
  • 返回 target 对象
1const target = { a: 1, b: 2 }
2const source = { b: 4, c: 5 }
3const returned = Object.assign(target, source)
4
5console.log(target) // Object { a: 1, b: 4, c: 5 }
6console.log(returned) // Object { a: 1, b: 4, c: 5 }
  • 会调用源对象的 [[Get]]
  • 和目标对象的 [[Set]]

Object.keys()

1const user = {
2  name: 'tom',
3  age: 25,
4}
5
6const keys = Object.keys(user) // ['name','age'] 返回键的数组,参数可以是原型对象
7
8// 只遍历键
9for (const key of Object.keys(obj))
10  console.log(key)

Object.values()

1const user = {
2  name: 'tom',
3  age: 25,
4}
5const keys = Object.values(user) // ["tom", 25]
6
7// 只遍历值
8
9for (const item of Object.values(obj))
10  console.log(item)

Object.entries()

  • 遍历键和值

  • 以二维数组的形式,将对象中的每个键名和键值,进行数组分解。

1for (const [key, item] of Object.entries(obj))
2  console.log(item, key)

Object.getOwnPropertyNames()

1Object.getOwnPropertyNames(Person.prototype) // ["constructor", "name", "job", "sayName"] 返回键的数

包含 constructor

不包含 Symbol 属性

Object.getOwnPropertySymbols()

1Object.getOwnPropertySymbols(obj)
2// 参数:要返回 Symbol 属性的对象。
3// 返回值:对象自身上找到的所有 Symbol 属性的数组。
4
5var obj = {}
6const a = Symbol('a')
7const b = Symbol.for('b')
8
9obj[a] = 'localSymbol'
10obj[b] = 'globalSymbol'
11
12const objectSymbols = Object.getOwnPropertySymbols(obj)
13console.log(objectSymbols.length) // 2
14console.log(objectSymbols) // [Symbol(a), Symbol(b)]
15console.log(objectSymbols[0]) // Symbol(a)

Object.getOwnPropertyDescriptors()

返回同时包含常规和符号(symbol)属性描述符的对象,都没有则返回空对象

1Object.getOwnPropertyDescriptors({ a: 1 })
2/* {
3  a:{
4    configurable: true
5    enumerable: true
6    value: 1
7    writable: true
8  }
9} */

Object.is()

1Object.is(value1, value2)
2// 比较两个值是否相等,与 == 和 === 不一样。返回 true/false
3
4Object.is('foo', 'foo') // true
5Object.is(window, window) // true
6Object.is([], []) // false
7
8const foo = { a: 1 }
9const bar = { a: 1 }
10Object.is(foo, foo) // true
11Object.is(foo, bar) // false
12Object.is(null, null) // true
13
14// 特例
15Object.is(0, -0) // false
16Object.is(0, +0) // true
17Object.is(-0, -0) // true
18Object.is(Number.NaN, 0 / 0) // true

Object.getPrototypeOf()

1Object.getPrototypeOf(object) // 返回参数的原型对象,没有继承属性则返回 null
2Object.getPrototypeOf(Object) // ƒ () { [native code] }
3Object.getPrototypeOf(Function) // ƒ () { [native code] }
4Object.getPrototypeOf(Object) === Function.prototype // true
5
6const obj = new Object()
7Object.prototype === Object.getPrototypeOf(obj) // true
8Object.prototype === Object.getPrototypeOf({}) // true

Object.freeze()

1Object.freeze(obj) // 返回被冻结的对象; 返回传递的对象,不是创建一个被冻结的副本
2// 冻结一个对象,冻结后不能添加删除,包括配置,可枚举,可写性等;也包括原型上的属性

Object.seal()

1Object.seal(obj) // 返回被封闭的对象的引用
2// 阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
3// 不会影响从原型链上继承的属性。但 __proto__ 属性的值也会不能修改。

Object.hasOwnProperty()

返回属性名是否在实例属性上

1const obj = {}
2obj.prop = 42
3console.log(obj.hasOwnProperty('prop')) // true
4console.log(obj.hasOwnProperty('toString')) // false