个人学习
Object.create
Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)
Object.create有两个参数:
proto新创建对象的原型对象propertiesObject新创建对象的属性,默认值为undefined,为新创建的对象添加指定的属性值和对应的属性描述符。
属性描述符 `跟defineProperty的描述符对象一 一对应的`
value:属性值,
writable:是否可写(修改)的,默认为false,
configurable:是否可配置的(能否通过`delete`删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,),默认为false,
enumerable:是否可遍历的,默认值为false
栗子
const obj = Object.create({a:1},{
b:{
value:2,
writable:true,
configurable:true,
enumerable:true
},
c:{
value:3,
writable:true,
configurable:true,
enumerable:false
}
})
console.log(obj)
// 遍历obj对象
// 由于obj.c属性设置enumerable为false 所以不可遍历出来
for (let key in obj){
//Object.hasOwnProperty.call(obj,key) // 判断对象是否是原型上的,第一个参数是目标对象,第二个参数是key
if(Object.hasOwnProperty.call(obj,key)){
console.log('原型对象上的属性:',obj[key])
}else{
console.log('obj对象的属性:',obj[key])
}
}
创建没有原型对象的对象
// 通过传递null 实现
const obj = Object.create(null,{
a:{
value:1
},
b:{
value:2
}
})
console.log(obj)
let obj = Object.create(null)
obj = {a:1,b:2} // 此时obj将会有原型,因为{a:1,b:2} 是由new Object构造出来的
Object.assign
Object.assign方法将源对象自有的(不可以是原型链的属性Object.hasOwnProperty返回true)中所有可枚举的属性复制到目标对象
两个参数
- target:目标对象,接收源对象属性的对象
- sources:源对象(可以是多个)
栗子
const test1 ={a:1,b:2}
const test2 ={c:3,d:4}
const test3 ={e:5,f:6}
const test4 = Object.assign(test1,test2,test3)
console.log(test1)
console.log(test4)
当在其中一个test用例的原型添加属性,这几个test用例的原型上都会有
const test1 ={a:1,b:2}
const test2 ={c:3,d:4}
const test3 ={e:5,f:6}
const test4 = Object.assign(test1,test2,test3)
test1.__proto__.x = 88
test3.__proto__.y = 99
Object.prototype.z = 100
console.log(test4)
是因为他们的原型都指向Object.prototype
console.log(test1.__proto__ === Object.prototype)// true
console.log(test1.__proto__ === test2.__proto__)// true
console.log(test4.__proto__ === test2.__proto__)// true
将下面用例添加到v5对象中
// 如果源对象不是对象格式,会将其进行转换成对象格式,然后将源对象中可枚举的属性分配给 target
const v1 = 123,v2 = '123',v3 = true, v4 = function test(){}
/* 转化过程
v1 = new Number(123)
v2 = new String('123')
v3 = new Boolean(true)
v4 = new Function(test)
*/
// 其中v1,v3,v4的对象格式都是不可以枚举的
const v5 = Object.assign({},v1,v2,v3,v4)
Object.assing是深拷贝还是浅拷贝?
- 对象的浅拷贝:浅拷贝是对象之间共用的一个内存地址,对象的变化相互影响。
- 对象的深拷贝:简单理解深拷贝是将对象放到新的内存中,两个对象的改变不会相互影响。
// 此时是深拷贝
let target = Object.defineProperty({},'a',{
value:1, //
writable:true
})
let res = Object.assign({},target,{b:3},{c:4})
// 不会影响到res
target.a = 10
console.log(res)
console.log(target)
现在修改一下a的值,将他的值改为引用数据类型
let target = Object.defineProperty({},'a',{
value:{name:'张三',age:18}, // 改为引用数据类型
writable:true
})
let res = Object.assign({},target,{b:3},{c:4})
target.a.name = '老王'
res.a.age = 30
// 此时值会互相改变
console.log(res)
console.log(target)
总结
对于Object.assign的浅拷贝还是深拷贝,是要看他复制的对象属性值的类型,当值是基本数据类型的时候此时Object.assign是深拷贝,不会相互影响,但当值是引用数据类型时,此时Object.assign就是浅拷贝,会互相影响
文章内容来自: csdn博主 b站up主前端小野森森