JS 常用对象方法总结

1.Object.create()

新建一个对象,新建对象拥有指定原型和若干个指定属性

接收两个对象参数

proto:必选,新建对象的原型对象

propertiesObject:可选,给新建对象创建一些指定属性

用法

​
const obj = {
  name: 'jack',
  printName: function() {
    console.log(`my name is ${this.name}`)
  }
}

obj.printName() // my name is jack

const test = Object.create(obj, {
  'old': {value:17, writable: false, configurable: false, enumerable: false},
  'type': {value:'hot girl', writable: true, configurable: true, enumerable: true},
})
test.name = 'rose'
test.printName() // my name is rose
console.log(test.old) // 17
console.log(test.type) // hot girl

​

Object.create的第一个参数是obj,作为新建对象test的原型,test继承obj的name、printName属性,其中printName是一个方法,所以test.name重新赋值,test.printName()输出了重新赋值后的语句

Objec.create的第二个参数也是对象,但对象内容是键值对,其中值还是一个对象,配置以下4个参数,参数描述此属性的行为

(1)value:属性指定的值

(2)enumerable:当且仅当该属性可被循环遍历时,为true

(3)writable:当且仅当该属性值可改变时,为true

(4)configurable:当且仅当该属性即可被更改,也可被删除时,为true

注:1.Object.create、Object.defineProperty、Objec.defineProperties 函数添加数据属性,writable、enumerable和configurable默认值为false。
       2.使用对象直接创建的属性,writable、enumerable和configurable特性默认为true

以下测试writable,enumerable,configurable,紧接着上面代码举例:

// 测试enumerable属性
for (let i in test) { 
  console.log(i) // type name printName 
}

以上代码遍历了test对象的属性,可看到只有3个属性输出,因为属性old的enumerable的值是false,使得old无法被遍历

// 测试writable属性
test.old = 18
console.log(test.old) // 17
test.type = 'bad girl'
console.log(test.type) // bad girl

以上代码分别修改了属性old和type,其中old的writable属性是false,说明old的值不能改变,所以test.old=18无效,输出仍然为17,而test.type能够正常输出改变后的值

// 测试configurable属性
console.log(test.type) // hot girl
delete test.type
console.log(test.type) // undefined

以上代码在删除type属性前正常输出,因为type的configurable是true,表示可删除,顾delete语句可删除type属性,重新输出后已找不到type属性,故输出undefined

2.Object.assign(target, source1, source2, ...., sourceN)

将源对象(source)的所有可枚举属性复制到目标对象上(target)

注:1.此方法只能复制源对象自身的属性(不复制继承属性),也不复制不可枚举的属性 

       2.如果复制时存在同名属性,则后面的属性值覆盖前面的属性值

       3.此方法属于浅复制,而不是深复制,如果源对象某个属性的值是对象,那么目标对象复制得到的是这个对象的引用;由于此缘故,源对象的属性应该是简单的属性值,而不该指向另一个对象

举例:

const obj = {
  name: 'jack',
  printName: function() {
    console.log(`my name is ${this.name}`)
  },  
  url: {
    host: 'hello.com',
    port: 8080
  }
}

let test = {}
Object.assign(test, obj)

test.printName() // my name is jack
console.log('url', test.url) // url { host: 'hello.com', port: 8080 }

以上代码成功通过Object.assign()将obj的属性拷贝到test上

以下分别对上面提出的注意点举例

(0) 只能复制源对象自身的属性,不复制继承属性

let objA = {
  x: '1'
}

let objB = {
  y: '2'
}

let objC = {
  z: '3'
}

Object.setPrototypeOf(objB, objA) // 此方法在下文中提到,设置objA为objB的原型属性,objA继承属性x
Object.assign(objC, objB)
console.log(objC) // { z: '3', y: '2' }

以上代码中,objC最终没有输出属性x,因为objB中的属性x属于继承属性

(1) 不复制不可枚举的属性

let obj = {
  name: 'jack'
}
Object.assign(obj, Object.defineProperty({}, 'old', {
  value: '17',
  enumerable: false
}))

console.log(obj) // { name: 'jack' }

Object.assign()的第二个参数返回一个对象,此对象包含一个不可遍历的属性old,从输出结果可看到并没有输出此属性,验证此方法不复制不可枚举的属性

(2) 如果复制时存在同名属性,则后面的属性值覆盖前面的属性值

let obj = {
  name: 'jack'
}
Object.assign(obj, {
  name: 'rose'
})

console.log(obj) // { name: 'rose' }

以上代码中,源对象的name属性覆盖了obj中的name属性

(3)  此方法属于浅复制,而不是深复制,如果源对象某个属性的值是对象,那么目标对象复制得到的是这个对象的引用

let target = {}

let source = {
  info: {
    name: 'jack'
  }
}

Object.assign(target, source)

console.log(target) // { info: { name: 'jack' } }
source.info.name = 'rose'
console.log(target) // { info: { name: 'rose' } }

以上代码中,当更改source中的对象的属性时,target的对象的相应属性随之改变,可以看出目标对象拷贝的是源对象的引用,即它们指向同一个对象

(4) 由于Object.assign()实现的是浅复制,源对象的属性应该是简单的属性值,而不该指向另一个对象

let target = {
  info: {
    name: 'jack',
    old: '17'
  }
}

let source = {
  info: {
    name: 'rose'
  }
}

Object.assign(target, source) 

console.log(target) // { info: { name: 'rose' } }

从以上代码可看出,通常情况下,我们期望source中的info的name属性值覆盖掉target的info的name属性值。从结果上看,确实做到了这一点,但是把old属性覆盖掉了,我们通常不希望这样的事情发生,也反向证明此方法无法进行深拷贝

3.Object.is()

比较两个值是否严格相等,与严格相等运算符(===)的行为基本一致

在JS中比较两个值是否相等有相等符号(==)和严格相等符号(===),这两个符号都存在一定的缺陷,前者会自动转换数据类型,后者的NaN===NaN返回结果为false以及+0===-0返回true,这不符合我们的期待,Object.is()满足了这种条件,在所有环境中,当两个值是一样的,他们就相等

console.log(Object.is(+0, -0)) // false
console.log(Object.is(NaN, NaN)) // true

4.Object.getOwnPropertyDescriptors()

获取对象某个属性的描述对象

let obj = {
  name: 'jack'
}

console.log(Object.getOwnPropertyDescriptor(obj, 'name'))
// { value: 'jack', writable: true, enumerable: true, configurable: true }

以上代码中,Object.getOwnPropertyDescriptor()方法返回一个对象,这个对象描述了属性name,分别是value,writable,enumerable,configurable具体含义上本有描述,此处不再重复

5.Object.defineProperty()

在对象上定义一个新属性,或修改原属性的行为

参数:

obj:必选,要定义属性的对象

prop: 必选,作用的属性名称

descriptor: 必选,要定义或修改的属性描述对象

let obj = {}
Object.defineProperty(obj, 'name', {
  value: 'jack',
  enumerable: true
})
console.log(obj) // { name: 'jack' }

以之相对还有一个Objec.defineProperties()方法,此方法能同时定义多个属性

let obj = {}
Object.defineProperties(obj, {
  'name': {
    value: 'jack',
    enumerable: true
  },
  'old': {
    value: 17,
    enumerable: true
  }
})

console.log(obj) //{ name: 'jack', old: 17 }

6~8为对象属性的遍历相关方法,不再一一举例,遍历对象还可用for...in,此循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)

6.Object.getOwnPropertyNames()

返回一个数组,包括对象自身的所有属性(不含Symbol属性但包括不可枚举属性)

7.Object.getOwnPropertySymbols()

返回一个数组,包括对象自身的所有Symbol属性

8.Object.ownKeys()

返回一个数组,包含对象自身的所有属性,不管是否是Symbol,也不管是否可枚举

9.Object.setPrototypeOf()

设置一个对象的原型对象,返回对象本身

let proto = {}
let obj = {
  type: 'hot girl'
}
Object.setPrototypeOf(obj, proto)
proto.name = 'rose'
proto.old = '17'
console.log(obj.name, obj.old) // rose 17

以上代码中,proto对象是obj的原型对象,所以通过设置proto的属性值,在obj中能够获取到

10.Object.getPrototypeOf()

用于读取一个对象的原型对象

class Obj {

}
let obj = new Obj()

console.log(Object.getPrototypeOf(obj) === Obj.prototype) // true

11.Object.keys()

返回一个数组,成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键名

12.Object.values()

返回一个数组,成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键值

13.Object.entries()

返回一个数组,成员是参数对象自身的(不含继承的)所有可枚举(enumerable)属性的键值对

11~13例子:

let obj = {
  name: 'rose'
}

Object.defineProperties(obj, {
  'old': {
    value: '17',
    enumerable: true
  },
  'type': {
    value: 'hot girl',
    enumerable: false
  }
})

console.log(Object.keys(obj)) // [ 'name', 'old' ]
console.log(Object.values(obj)) // [ 'rose', '17' ]
console.log(Object.entries(obj)) // [ [ 'name', 'rose' ], [ 'old', '17' ] ]

以上代码中,除了属性name,分别定义了可枚举属性old和不可枚举属性type,输出即为定义所描述

 

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值