Object.defineProperty()&利用它做数据代理

241 阅读2分钟

Object.defineProperty()

基本用法
三个参数(给那个对象添加属性 , 属性叫什么 , {配置项} )
Object.defineProperty('给那个对象添加属性' , '添加的属性叫什么' , { //配置项
	value:18
})

-----------------------------------------------------------

比如 我给person加一个age = 18
let person = {
    name: "张三",
    sex: "男"
}
Object.defineProperty(person, 'age', {
	value: 18
})
console.log(person)

打印的时候你会发现person的age项是淡色的 说明他不会被枚举
如果要枚举 则增加一个配置项 增加的值也不能改也不能删除
Object.defineProperty(person, 'age', { //配置项
    value: 18,
    enumerable: true, //控制属性是否可以被枚举 默认false
    writable: true, //控制属性是否可以被修改 默认false
    configurable:true //控制属性是否可以被删除 默认false
})

接下来引出高级的

let number = 18
let person = {
    name: "张三",
    sex: "男",
    age:number
}
这样写的时候 number变 person里的age不会跟着变
拿的不是同一个地址

但是我想number变person里的age也变,person的age变number也变,怎么办呢?
先引入一个新的配置项 还是之前的person
Object.defineProperty(person, 'age', { //配置项
    //当有人读取person的age属性时 get(getter)就会被调用 且返回值就是age的值
    get:function(){
    	return 'hello'
    }
})
logperson后你会发现 age:(...) 意思为必须得点击(年龄多少我不知道 我得问问getter)
而且还会多一个属性 get age : f() 为age服务

所以直接这样就可以和number绑定
Object.defineProperty(person, 'age', { //配置项
    get(){
		return number
    }
})


还一个set也类似
let number = 18
let person = {
    name: "张三",
    sex: "男",
}
Object.defineProperty(person, 'age', { //配置项

    //当有人读取person的age属性时 get(getter)就会被调用 且返回值就是age的值
    get() {
        console.log('getter');
        return number
    },
    //当有人修改person的age属性时 set(setter)就会被调用 且会收到修改的具体值
    set(value) {
        console.log('setter');
        number = value
    }

})

数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)

let obj1 = {
	x:100
}
let obj2 = {
	y:200
}

Object.defineProperty(obj2, 'x', {
	get() {
		return obj1.x
	},
	set(value) {
		obj1.x = value
	}
})

这样可以通过操作obj2里面的x来修改obj1里面的x