1.Object.prototype.hasOwnProperty()对象,所有实例对象都可访问
方法:hasOwnProperty表示是否是对象自身的属性。
这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链
沿原型链上查找的方法不是它自身的
let obj = {
name: jack,
age:18
}
obj.hasOwnProperty('name') //返回true
//hasOwnProperty表示是否是对象自身的属性.判断name是不是obj对象自身的属性
![](https://img-blog.csdnimg.cn/7da16736d5aa4bc5a95c7514a5faeb74.png)
2.Object.defineProperty() 是一个Object类对象的方法
作用:1>将对象的属性绑定到另一个对象上
let obj = {
name: 'jack',
age: 18,
}
let vm = {}
// 将obj对象的所有属性动态添加到vm对象上
//1. 遍历obj对象
for (const key in obj) {
// 2. 动态给vm添加属性
Object.defineProperty(vm, key, {
// vm.name
get() {
return obj[key]
},
// vm.name = 'rose'
set(newValue) {
// 原值与新值相同直接返回
if (obj[key] == newValue) {
return
}
obj[key] = newValue // 设置属性新值
},
})
}
2>实现数据劫持:监听对象数据变化,实现数据变化自动更新界面
<div>
<p class="title"></p>
</div>
<script>
let obj = {
name: 'jack',
age: 18,
}
let vm = {}
//将obj对象的所有属性动态添加到vm对象上
//1.遍历对象
for (const key in obj) {
//2.动态给vm添加属性
Object.defineProperty(vm, key, {
get() {
console.log('get')
return obj[key]
},
set(newValue) {
//原值与新值相同直接返回
if (obj[key] == newValue) {
return
}
obj[key] = newValue //设置属性新值
console.log('set')
//监听对象数据变化后执行其他操作
//更新界面
const titleEle = document.querySelector('.title')
titleEle.innerHTML = obj.name+' '+obj.age
},
})
}
语法:Object.defineProperty(obj, 'name',{})
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
let obj={}
Object.defineProperty(obj,'name',{ //动态添加name
value:'jack',
configurable:true, //允许删除属性
writable:true, //允许修改属性
enumerable:true, //允许遍历对象})
console.log(obj.name)
属性:
1.数据属性:configurable:true, //允许删除属性
writable:true, //允许修改属性
enumerable:true, //允许遍历对象
2.访问器属性:
1.get:在读取属性时调用的函数,默认值是undefined
let obj={}
Oject.defineProperty(obj,'age',{
get:function(){
return 20}
console.log(obj.age) //输出值为20 //obj访问age时会自动调用get方法
2..set:在写入属性的时候调用的函数,默认值是undefined
set(newValue){
obj.age=18 //修改属性值时,set自动调用
}
console.log(obj.age) //输出为18
proxy代理:
1.不直接对对象、函数或者数组进行操作,而是把它挂载到Proxy(代理)上,直接对代理的做一系列操作。
2.代理是使用 Proxy 构造函数创建的。这个构造函数接收两个参数:目标对象和处理程序对象。缺少其中任何一个参数都会抛出 TypeError。
let obj={
name:'jack',
age:18
}
let handler={} //处理程序
let proxyObj= new Proxy (obj,handler) //代理对象
proxyObj.name='rose' //通过代理对象操作目标对象
function test1() {
// 目标对象
let obj = {
name: 'jack',
age: 18,
}
// 处理程序
let handler = {}
// 代理对象
let proxyObj = new Proxy(obj, handler)
// 通过代理对象操作目标对象和直接操作目标对象是一样的效果,
console.log('obj.name ', obj.name)
console.log('proxyObj.name ', proxyObj.name)
proxyObj.name = 'rose' // 通过代理对象更改目标对象属性值
console.log('obj.name ', obj.name)
}
捕获器:
1.get捕获器,get()
通过代理对象获取目标对象属性值时触发
// get(){
// return '这是代理给的新值'
// }
2.set捕获器,set()
// 通过代理对象给属性设置值触发
// 通过代理对象操作目标对象时,可以对目标对象做一些拦截操作, 在处理程序handler中设置
// 目标对象
let obj = {
name: 'jack',
age: 18,
}
// 处理程序
let handler = {
// 通过代理对象获取目标对象属性值时触发
// get(){
// return '这是代理给的新值'
// }
// get参数
get(target,propery,receiver){
console.log('target ',target)
console.log('propery ',propery)
console.log('receiver ',receiver)
return target[propery]
},
// 通过代理对象给属性设置值触发
set(target,propery,value,receiver){
console.log('set >>>');
console.log('target ',target)
console.log('propery ',propery)
console.log('value ',value)
console.log('receiver ',receiver)
target[propery] = value
}
}
// 代理对象
let proxyObj = new Proxy(obj, handler)
// console.log( proxyObj.age )
proxyObj.age = 20
通过Proxy代理目标对象obj,实现数据劫持-通过代理对象proxy改变目标对象属性值时,在get,set捕获器方法中做一些处理, 比如更新界面
<div></div>
let obj = {
message:''
}
let proxyObj = new Proxy(obj,{
get(target,propery){
return target[propery]
},
set(target,propery,value){
target[propery] = value // 通过代理对象改变目标对象属性值
// 更新界面操作-更改div内容
document.querySelector('div').innerHTML = value
}
})
proxyObj.message = 'hello'
深拷贝和浅拷贝:
1.浅拷贝:复制的obj对象只复制一层,如果对象属性值是对象则不能复制
![](https://img-blog.csdnimg.cn/f50a4ea49d75490eaa9e20b14720927f.jpeg)
2.深拷贝:完全复制的obj对象,如果对象属性值是对象一起复制得到全新对象
![](https://img-blog.csdnimg.cn/292b8ab52d3b4c219c7e6fe12cda97a4.png)
实现方式:
1.展开运算符{…obj},实现浅拷贝
缺点:只能拷贝一层,如果属性值是对象,无法拷贝
let obj = {
name: 'jack',
age: 18,
fun: {
swiming: '游泳',
},
}
let newObj = { ...obj } // 浅拷贝,如果属性值是对象不能拷贝
newObj.name = 'rose'
newObj.fun.swiming = '打游戏'
console.log('newObj :',newObj.name, ' oldObj :',obj.name);
console.log('newObj fun :',newObj.fun.swiming, ' oldObj fun :',obj.fun.swiming);
console.dir(newObj);
console.dir(obj);
2.JSON.parse(JSON.stringify(obj))
缺点: 数据类型是Function或数据值为undefined无法拷贝
let str = JSON.stringify(obj) //obj->str
可以将对象转成JSON字符串
注:对象只能是Object形式对象不是Math,Date
let newObj = JSON.parse(str) // str->obj
可以将JSON字符串转成对象
let objStr = JSON.stringify(obj)
console.log(obj)
console.log(objStr, typeof objStr)
let str = '{"num":1001,"score":98}'
let obj1 = JSON.parse(str)
console.log(obj1)
console.log(obj1.num)
利用JSON实现深拷贝:
let obj = {
name: 'jack',
age: 18,
fun: {
swiming: '游泳',
},
say:function(){
console.log('说话');
},
score:undefined
}
// 利用JSON实现深拷贝
// let str = JSON.stringify(obj) //obj->str
// let newObj = JSON.parse(str) // str->obj
let newObj = JSON.parse(JSON.stringify(obj))
newObj.name = 'rose'
newObj.age = 20
newObj.fun.swiming = '玩游戏'
console.dir(newObj)
console.dir(obj)
递归 cloneDeep(),实现深拷贝,解决JSON深拷贝问题
let newObj = Array.isArray(obj)? []:{} // 存储拷贝的原对象属性方法
for(const key in obj){
if(obj[key] && typeof obj[key] === 'object'){
newObj[key] = cloneObj(obj[key])
}else{
newObj[key] = obj[key]
}
}
return newObj
}
let obj = {
name: 'jack',
age: 18,
fun: {
swiming: '游泳',
},
say: function () {
console.log('说话')
},
score: undefined,
}
let newObj = cloneObj(obj)
newObj.name = 'rose'
newObj.age = 20
newObj.score = 98
newObj.fun.swiming = '玩游戏'
console.dir(newObj)
console.dir(obj)