一、Object.defineProperty
let person = {
name: 'zs',
age: 18
}
// Object.defineProperty(需要定义属性的对象,需要定义属性的名称,需要定义属性描述符)
Object.defineProperty(person, 'sex', {
value: '男',
// 以下默认值均为false
writable: true, // 允许被改变,
enumerable: true, // 允许被枚举,
configurable: true, // 允许被删除,
})
console.log(person) // {name: 'zs', age: 18, sex: '男'}
// 另一种改变格式,上面和这个格式只能二选一
Object.defineProperty(person, 'sex', {
get() {
// 访问该属性时会调用此函数
console.log('被访问了')
},
set(value) {
// 属性值被改变时会调用此函数
// value是被改变的值
console.log(value)
}
})
console.log(person.sex) // get()'被访问了'触发,person.sex打印undefined
console.log(person.sex = '男') //set()打印'男',person.sex = '男'打印男
二、Proxy
const person = {
name: 'zs',
age: 18
}
/* new Proxy(target, handle)
* target 目标对象
* handle 一个对象,可以不写,但是须以空{}占位
*/
const p = new Proxy(person,{
// 读取p的值时调用get
get(target, propName, receiver) {
/* target 传入的目标对象本身
* propName 访问对象属性的名字
* receiver Proxy实例本身
*/
console.log(target, propName, receiver)
return target[propName]
},
// 修改、增加p的值时调用
set(target, propName, value, receiver) {
// 与get的区别是多了value,value是被修改的值
console.log(target, propName, value, receiver)
return target[propName] = value
}
})
console.log(p.name) // {name: 'zs', age: 18} 'name' Proxy {name: 'zs', age: 18}
/*
* {name: 'zs', age: 18} get中的target,即person本身
* 'name' get中的propName,即访问的person的属性名称
* Proxy {name: 'zs', age: 18} get中的receiver,被代理的person的Proxy实例
*/
console.log(p.age = 20) // {name: 'zs', age: 18} 'age' 20 Proxy {name: 'zs', age: 18}
/*
* 与get相比只是多了value,value值为20
*/
console.log(person) // {name: 'zs', age: 20}
const p = new Proxy(person,{
// 删除p的值时调用
deleteProperty(target, propName) {
// 监听 delete 语句对目标对象的删除属性行为
return delete target[propName]
}
})
console.log(delete p.age, person) // true {name: 'zs}
// 模拟简易响应式
const p = (target)=>{
return new Proxy(target,{
// 读取p的值时调用get
get(target, propName, receiver) {
/* target 传入的目标对象本身
* propName 访问对象属性的名字
* receiver Proxy实例本身
*/
console.log(target, propName, receiver)
return target[propName]
},
// 修改、增加p的值时调用
set(target, propName, value, receiver) {
// 与get的区别是多了value,value是被修改的值
console.log(target, propName, value, receiver)
return target[propName] = value
}
})
}
const test = p({val: 1})
// 页面定义一个按钮
count.onclick = ()=>{
test.val++
}