美文网首页
【JavaScript】Object常用方法总结

【JavaScript】Object常用方法总结

作者: 远人村c | 来源:发表于2023-05-01 10:26 被阅读0次

前言

在 JavaScript 中,几乎所有的对象都是 Object 类型的实例,它们都会从 Object.prototype 继承属性和方法,虽然大部分属性都会被覆盖(shadowed)或者说被重写了(overridden)。 除此之外,Object 还可以被故意的创建,但是这个对象并不是一个“真正的对象”(例如:通过 Object.create(null)),或者通过一些手段改变对象,使其不再是一个“真正的对象”(比如说:Object.setPrototypeOf)。

静态方法

Object.create

创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。

let obj = Object.create(null)
let o1 = {
  name: 'abc',
  say() {
    console.log(this.name)
  }
}
let o2 = Object.create(o1)
o2.name = 'ABC'
o2.say() // ABC

Object.getPrototypeOf()

返回指定对象的原型(内部[[Prototype]]属性的值)。

function Foo() {}
let foo = new Foo()
Object.getPrototypeOf(foo) === Foo.prototype // true

Object.setPrototypeOf()

设置一个指定的对象的原型(即,内部 [[Prototype]] 属性)到另一个对象或null

const obj = {}
Object.setPrototypeOf(obj, null)

Object.getOwnPropertyDescriptors()

获取一个对象的所有自身属性的描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

const obj = {
  age: 18,
  name: 'A'
}
console.log(Object.getOwnPropertyDescriptors(obj))
/**
{
  age: { value: 18, writable: true, enumerable: true, configurable: true },
  name: { value: 'A', writable: true, enumerable: true, configurable: true }
}
**/

Object.getOwnPropertyDescriptor

获取对象上一个自有属性对应的属性描述符。

const obj = {
  age: 18,
  name: 'A'
}
console.log(Object.getOwnPropertyDescriptor(obj, 'age'))
// { value: 18, writable: true, enumerable: true, configurable: true }

Object.getOwnPropertyNames()

获取指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。

const obj = {
  age: 18,
  name: 'A',
  [Symbol('address')]: 'GZ'
}
console.log(Object.getOwnPropertyNames(obj)) // [ 'age', 'name' ]

Object.getOwnPropertySymbols()

获取指定对象自身的所有 Symbol 属性的数组。

const obj = {
  age: 18,
  name: 'A',
  [Symbol('address')]: 'GZ'
}
console.log(Object.getOwnPropertySymbols(obj)) // [ Symbol(address) ]

Object.hasOwn()

如果指定的对象自身有指定的属性,返回 true。如果属性是继承的或者不存在,返回 false

Object.assign()

将所有可枚举自有属性从一个或多个源对象复制到目标对象,返回修改后的对象。
如果目标对象与源对象具有相同的 key,则目标对象中的属性将被源对象中的属性覆盖,后面的源对象的属性将类似地覆盖前面的源对象的属性。

Object.fromEntries()

将键值对列表转换为一个对象

const entries = new Map([
  ['name', 'abc'],
  ['age', 20]
])
const obj = Object.fromEntries(entries)
console.log(obj) // { name: 'abc', age: 20 }

Object.is()

Object.is() 方法判断两个值是否为同一个值,如果满足以下任意条件则两个值相等:

  • 都是undefined
  • 都是 null
  • 都是 true 或都是 false
  • 都是相同长度、相同字符、按相同顺序排列的字符串
  • 都是相同对象(意味着都是同一个对象的值引用)
  • 都是数字且
    • 都是 +0
    • 都是 -0
    • 都是 NaN
    • 都是同一个值,非零且都不是 NaN

Object.is()== 不同。== 运算符在判断相等前对两边的变量(如果它们不是同一类型)进行强制转换(这种行为将 "" == false 判断为 true),而 Object.is 不会强制转换两边的值。

Object.is()=== 也不相同。差别是它们对待有符号的零和 NaN 不同,例如,=== 运算符(也包括 == 运算符)将数字 -0+0 视为相等,而将 Number.NaNNaN 视为不相等。

Object.freeze()

冻结一个对象。
不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值,对象的原型也不能被修改。
这个方法返回原对象,而不是创建一个被冻结的副本。
如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。数组作为一种对象,被冻结,其元素不能被修改。没有数组元素可以被添加或移除。

const obj = {
  age: 18,
  name: 'A',
  address: ['GX', 'DS']
}
console.log(Object.freeze(obj) === obj)
// obj.age = 20 // 报错
// delete obj.age // 报错
obj.address.push('SS') // 可以添加
obj.address.splice(0, 1) // 可以删除
// obj.address = [] // 报错

// 冻结一个数组
const arr = [1, 2, 3]
Object.freeze(arr)
arr.push(4) // 不能添加,当然也不能做其他修改

Object.isFrozen()

判断一个对象是否被冻结

Object.seal()

密封一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。

const obj = {
  age: 18,
  name: 'A'
}
Object.seal(obj)
delete obj.age // 不能删除属性,会报错
// obj.age = 20 // 添加属性,会报错

Object.isSealed()

判断一个对象是否被密封。
注意冻结对象也是一个密封对象。

Object.preventExtensions()

让一个对象变的不可扩展,也就是永远不能再添加新的属性。

const obj = {
  age: 18,
  name: 'A'
}
Object.preventExtensions(obj)
delete obj.age // 可以删除属性
obj.age = 20 // 添加属性则会报错

Object.isExtensible()

判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。\n
注意冻结对象也是一个不可扩展的对象。一个不可扩展的空对象同时也是一个冻结对象。

const obj = {
  age: 18,
  name: 'A'
}
Object.seal(obj)
console.log(Object.isSealed(obj)) // true
console.log(Object.isExtensible(obj)) // false密封属性同时也是不可以拓展的

const obj1 = {}
Object.preventExtensions(obj1)
console.log(Object.isFrozen(obj1)) // true 一个不可扩展的空对象同时也是一个冻结对象

Object.defineProperty()

语法:

Object.defineProperty(obj, prop, descriptor)
  • obj:要定义属性的对象。
  • prop:要定义或修改的属性的名称或 [Symbol]
  • descriptor:要定义或修改的属性描述符:
    • value:该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认undefined
    • writable:为 true 时,属性的值,也就是value,才能被赋值运算符改变。 默认false
    • configurable:为true时,该属性的描述符才能够被改变和删除。 默认false
    • enumerable:为 true 时,该属性才会出现在对象的枚举属性中。默认false
    • get:属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。
      执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认 undefined
    • set:属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认为undefined
function defineReactive(obj, key, val) {
  // 获取当前key的属性描述符
  const property = Object.getOwnPropertyDescriptor(obj, key)
  if (property && property.configurable === false) {
    return
  }
  const getter = property && property.get
  const setter = property && property.set
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key]
  }
  return Object.defineProperty(obj, key, {
    get() {
      const value = getter ? getter.call(obj) : val
      return value
    },
    set(newVal) {
      val = newVal
    }
  })
}
let obj = { a: 10 }
defineReactive(obj, 'a')
console.log(obj.a)

Object.defineProperties()

在一个对象上定义新的属性或修改现有属性,并返回该对象。

let obj = {}
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
})

Object.entries()

返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。

const obj = {
  name: 'abc',
  age: 18,
  [{}]: 'aa',
  [Symbol['address']]: 'China'
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`${key}: ${value}`)
}
/**
  name: abc
  age: 18
  [object Object]: aa
  undefined: China
 */

Object.keys()

返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序与使用for...in 循环的顺序相同。

const obj = {
  name: 'abc',
  age: 18,
  [{}]: 'aa',
  [Symbol['address']]: 'China'
}

for (const key of Object.keys(obj)) {
  console.log(key)
}
/**
  name
  age
  [object Object]
  undefined
 */

Object.values()

返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in 循环的顺序相同。

const obj = {
  name: 'abc',
  age: 18,
  [{}]: 'aa',
  [Symbol['address']]: 'China'
}

for (const value of Object.values(obj)) {
  console.log(value)
}
/**
  abc
  18
  aa
  China
 */

实例方法

Object.prototype.hasOwnProperty()

返回一个布尔值,表示对象自身属性中是否具有指定的属性。

const parent = {
  key: 'aaa'
}
const obj = Object.create(parent)
obj.age = 18
console.log(obj.age) // 18
console.log(obj.hasOwnProperty('age')) // true
console.log(obj.key) // aaa
console.log(obj.hasOwnProperty('key')) // false
// 也可以使用 Object 原型上的 hasOwnProperty 属性
console.log(Object.prototype.hasOwnProperty.call(obj, 'age')) // true

Object.prototype.isPrototypeOf

返回一个布尔值,表示一个对象是否存在于另一个对象的原型链上。

function Parent() {}
function Child() {}

Child.prototype = Object.create(Parent.prototype)
const child = new Child()
console.log(Parent.prototype.isPrototypeOf(child)) // true
console.log(Child.prototype.isPrototypeOf(child)) // true
console.log(Object.prototype.isPrototypeOf(child)) // true

Object.prototype.toString()

返回一个表示该对象的字符串。
Object.prototype.toString() 返回 [object Type],这里的 Type 是对象的类型。如果对象有 Symbol.toStringTag 属性,其值是一个字符串,则它的值将被用作 Type。许多内置的对象,包括 MapSymbol,都有 Symbol.toStringTag。一些早于 ES6 的对象没有 Symbol.toStringTag,但仍然有一个特殊的标签。它们包括(标签与下面给出的类型名相同):

  • Array
  • Function(它的 typeof 返回 "function")
  • Error
  • Boolean
  • Number
  • String
  • Date
  • RegExp
console.log(Object.prototype.toString.call(1)) // [object Number]
console.log(Object.prototype.toString.call('')) // [object String]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(function () {})) // [object Function]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(new RegExp(/\d/g))) // [object RegExp]
console.log(Object.prototype.toString.call(new Error())) // [object Error]
console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
console.log(Object.prototype.toString.call(123n)) // [object BigInt]

// 自定义
let obj = {
  [Symbol.toStringTag]: 'MyObj'
}
console.log(Object.prototype.toString.call(obj)) // [object MyObj]

Object.prototype.valueOf()

this 值转换为一个对象。此方法旨在用于自定义类型转换的逻辑时,重写派生类对象。

function MyNumberType(n) {
  this.number = n
}

MyNumberType.prototype.valueOf = function () {
  return this.number
}

const object1 = new MyNumberType(4)

console.log(object1 + 3) // 7

相关文章

网友评论

      本文标题:【JavaScript】Object常用方法总结

      本文链接:https://www.haomeiwen.com/subject/gmsojdtx.html