参考javascript忍着秘籍(第二版),有兴趣的可以去看下,由浅入深恶补js基础。
一、 getter和setter来控制属性访问
代理是我们通过代理控制对另一个对象的访问。通过代理可以定义当对象发生交互时可执行的自定义行为——如读取或设置属性值,或调用方法。
在JavaScript中,可以通过两种方式定义getter
跟setter
。
- 通过对象字面量定义,或者在ES6的class中定义
- 通过使用内置的
Object.defineProperty
方法。
接下来我们将用两种方式里分别实现getter跟setter。
1. 在es6的class中使用getter和setter
class NinjaCollection {
constructor() {
this.ninjas = ['Slim', 'Beautiful', 'Lovely']
}
get firstNinja() {
console.log('Getting firstNinja')
return this.ninjas[0]
}
set firstNinja(value) {
console.log('Setting firstNinja')
return this.ninjas[0] = value
}
}
const ninjiaCollection = new NinjaCollection();
console.log(ninjiaCollection.firstNinja === 'Slim', '第一次取值')
ninjiaCollection.firstNinja = 'Kind'
console.log(ninjiaCollection.firstNinja === 'Slim', 'Error: 重新赋值后的取值')
console.log(ninjiaCollection.firstNinja === 'Kind', '重新赋值后的取值')
运行结果如下:
通过日志我们可以很清楚明了的看清set和get的工作内容。
2. 通过使用内置的Object.defineProperty
方法
get:指读取属性时调用的函数。
set:指写入属性时调用的函数。
看下面这个例子,我们来了解下写入与读取
let ninja = {
name:'小花',
age:16
}
ninja.age = 17;
ninja.age = 18;
console.log('===>1',ninja.age)
Object.defineProperty(ninja,'age',{
set:function(newAge){
console.log(this.name+'现在'+newAge+'岁')
},
get:function(){
return 16;
}
})
//赋值
ninja.age = 17;
ninja.age = 18;
console.log('===>2',ninja.age)
可以先猜下console.log1跟console.log2的结果,第一个是没有对get
、set
做任何操作。第二个是我们自定义了get
、set
函数。
运行结果如下:
在这里看到,我们获取ninja.age
的时候只能是得到16,因为本质上ninja={ name: '小花', age: [Getter/Setter] }
,也就是说我在使用ninja.age
方法时候是在使用get
方法,而get
方法返回值一直是16,所以我一直获取不了最新的值。
想要达到get跟set同步的目的可以添加一个属性值_age
,来看这个例子
let ninja = {
name:'小花',
_age:16
}
ninja.age = 17;
ninja.age = 19;
Object.defineProperty(ninja,'age',{
set:function(newAge){
this._age = newAge
console.log(this.name+'现在'+newAge+'岁')
},
get:function(){
return this._age;
}
})
ninja.age = 13
运行结果如下:
到这儿为止,我们已经基本了解js中对象内get、set的工作原理。
二、使用代理(proxy
)控制访问 ,代理来捕获get、set
接着使用上面的例子,通过代理来get
、set
进行操作
let ninja = {
name:'小花',
_age:16
}
const handers = {
get() {
// 进行取值时会触发
return this._age;
},
set() {
// 进行赋值时会触发
this._age = newAge
console.log(this.name+'现在'+newAge+'岁')
},
}
const observed = new Proxy(target, handers)
如有问题请联系我~