当前位置:   article > 正文

Object对象的一些方法_obj[]写法,obj是个对象

obj[]写法,obj是个对象

Object.assign()

语法:Object.assign(target,…sources)
参数:
target:目标对象,接收源对象属性的对象,也是修改后的返回值
sources:源对象,包含将被合并的属性
返回值:目标对象

1.Object.assign()方法将所有可枚举(Object.propertyIsEnumerable()返回true)和自有(Object.hasOwnProperty()返回true)属性从一个或多个源对象复制到目标对象,返回修改后的对象

const obj1 = {name:"zs",age:12}
const obj2 = {name:"ls",sex:1}
Object.assign(obj1,obj2)
// obj1 : {name: 'ls', age: 12, sex: 1}
// obj2 : {name: 'ls', sex: 1}

const obj3 = {id:1,num:12}
const obj4 = {pro:"123",id:123}
Object.assign(obj2,obj3,obj4)
// obj2 : {name: 'ls', sex: 1, id: 123, num: 12, pro: '123'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.如果目标对象与源对象有相同的key,则目标对象中的属性将被源对象中的属性覆盖,后面的源对象的属性将类似地覆盖前面的源对象属性

3.如果赋值期间出错,例如属性不可写,则会抛出异常.如果在抛出异常前添加了如何属性,则会修改target对象.(译者注:Object.assign()没有"回滚"的概念,它是一个尽力而为,可能只会完成部分复制的方法).

备注:Object.assign()不会在source对象值为null或者undefined时抛出错误
const obj = {name:"zs"}
Object.assgin(obj,null) 
//不会报错,返回{name:"zs"}     obj的值为{name:"zs"}
Object.assign(obj,undefined)
//不会报错,返回{name:"zs"}     obj的值为{name:"zs"}
  • 1
  • 2
  • 3
  • 4
  • 5
const obj = Object.defineProperty({},'foo',{
    value:"zs",
    writeable:false
})
//obj:{foo:"zs"}
Object.assign(obj,{name:"ls"},{foo:"ls"},{name:"wq"},{age:12})
//报错:Uncaught TypeError: Cannot assign to read only property 'foo' of object '#<Object>'
//该foo属性只读,不可写入,抛出异常打断了后续的复制,没有报错前的复制依然保留
//obj的值为{name: 'ls', foo: 'zs'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

4.Object.assign()复制的是属性值,若源对象是一个对象的引用,它仅仅会复制其引用值

const obj = {children:12}
const person = {
    children:{
        name:"zs",
        age:12
    }
}
Object.assign(obj,person)

obj的值为:{
	children:{
        name:"zs",
        age:12
    }
}
obj.children === person.children ?    //  true
Object.assign(obj,JSON.parse(JSON.stringify(person)))
obj.children === person.children ?    //  false

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

5.原型链上的属性和不可枚举的属性不能被复制

function Student(name,age){
    this.name = name
    this.age= age
}
Student.prototype.cusName = "hulk"

const xm = new Student("xm",12)
//xm的值为{name:"xm",age:12}
xm.cusName // "hulk"

Object.defineProperty(xm,"sex",{
    enumerable:false, //不可被枚举
    value:"男"
})
//xm的值为{name:"xm",age:12,sex:"男"}
const obj = {}
Object.assign(obj,xm)
//obj的值为{name:"xm",age:12}
obj.cusName //undefined  无法访问到源对象原型链上的东西
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Object.defineProperty()

object.defineProperty()方法会直接在一个对象上定义一个新的属性,或者修改一个对象的现有属性,并返回此对象

语法:Object.defineProperty(obj,prop,descriptor)
参数:
obj:要定义的对象
prop:要定要或者修改的属性的名称或者symbol
descriptor:要定义或者修改的属性的描述符

descriptor:{

​ configurable //默认值false,配置对象属性是否可被删除

​ enumerable //默认值false,配置对象属性是否可被枚举

​ value //默认值undefined,属性的值,可以是任何有效的JavaScript值

​ writable //默认值false,配置对象的属性是否可被改变

​ getter //函数,当访问属性时,触发该函数,该函数返回对象一般是被访问的属性的值

​ setter //函数,当属性的值被修改时,触发该函数,该函数接受一个参数,也就是被赋予的新值.

}

返回值:被传递给函数的对象
const obj = {}
Object.defineProperty(obj,'name',{
    value:3
})

obj.name = 1  //obj的值为{name:3}  ,表明obj自身的属性"name"不能被修改
obj.propertyIsEnumerable('name')   // false ,标识name属性不能被枚举
delete obj.name //返回false  ,表明obj的属性name不可被删除

const obj1 = {}
var tempValue
Object.defineProperty(obj1,'name',{
    get:()=>{
		console.log("getter被访问")
		return tempValue
	},
    set:(value)=>{
        console.log("setter被访问")
		tempValue = value
    }
})
obj1.name // undefined ,控制台打印"getter被访问"
obj1.name = "zs" // 'zs',控制台打印"setter被访问"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

每个对象都有propertyIsEnumerable()方法,这个方法可以判断出指定的属性是否可枚举。
用法:obj.propertyIsEnumerable(“属性名”);

描述:对象里面目前存在的属性描述符有两种主要形式:数据描述符和存取描述符.数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的.存取描述符是由getter函数和setter函数所描述的属性.一个描述符只能是这两者其中之一,不能同时是两者.

以上一段话是MDN官方描述,解读下来就如下:

//第一种写法
const obj = {}
Object.defineProperty(obj,'name',{
    value:"zs",
    //以下是配置是否可枚举,是否可写入,是否可被删除
    enumerable:true,
    writable:true,
    configurable:true
})
obj.name // 读取到的值为:'zs'

//第二种写法
const obj = {}
Object.defineProperty(obj,'name',{
    get(){
        return this._name
    },
    set(value){
        this._name = value
    }
})

//不可以写成以下这样
const obj = {}
Object.defineProperty(obj,'name',{
    value:"zs",
    get(){
        return this._name
    },
    set(value){
        this._name = value
    }
})

//两种写法只能存在其一,不能两者都写
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
描述符可以拥有的键值
configurableenumerablevaluewritablegetset
数据描述符truetruetruetruefalsefalse
存取描述符truetruefalsefalsetruetrue

1.如果属性已存在,Object.defineProperty()将尝试根据描述符中的值以及对象当前的配置来修改这个属性.如果旧描述符将其configurable的属性为false,则该属性被认为是’不可配置的’,并且没有属性可以被改变(除了单项改变writable为false).当属性不可配置时,不能在数据和访问器属性类型之前切换.

这又是官方的说法,看半天难以理解,换成代码就是以下说法:

//首先先定义一个属性
const obj = {}
Object.defineProperty(obj,'name',{
    value:1,
    writable:true
})
//然后再对这个已存在的属性进行下一次定义
Object.defineProperty(obj,'name',{
    value:12,
    writable:false
})
console.log("obj的值为:",obj.name) //12 ,此时是可以修改value和writable的

//但是不能再对该属性的enumerable和configurable进行配置,会报错,除非配置的值是一样的
Object.defineProperty(obj,'name',{
    value:12,
    configurable:true
}) //这种是错误的,不能在配置了

//同样存取描述符也会抛出异常
Object.defineProperty(obj,'name',{
    get(){
        return 1
    },
    set(value){
        
    }
}) //抛出异常:Uncaught TypeError: Cannot redefine property: name 不能重新定义该字段
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
使用构造函数来创建一个新的对象
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/68136
推荐阅读
相关标签
  

闽ICP备14008679号