參考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)
如有問題請聯繫我~