原生JavaScript實現觀察者模式
阿新 • • 發佈:2019-01-04
什麼是觀察者模式
維基百科對觀察者模式的定義如下:
觀察者模式是軟體設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實時事件處理系統。
說的簡單些,就是在資料發生改變時,對應的處理函式自動執行。維基的定義中涉及到了主動發出通知,按照這種方式,在angularJS中的事件廣播更是中規中矩,但是其缺點是程式碼的可維護性較差。那麼如果不進行主動通知,而是在進行物件屬性值設定時,呼叫相關的處理函式,也可達到同等效果。如下見詳細程式碼。
ES5下的實現
在ES5中主要是通過Object.defineProperty
// 建立物件
var targetObj = {
age: 1
}
// 定義值改變時的處理函式
function observer(oldVal, newVal) {
// 其他處理邏輯...
console.info('name屬性的值從 '+ oldVal +' 改變為 ' + newVal);
}
// 定義name屬性及其set和get方法
Object.defineProperty(targetObj, 'name', {
enumerable: true,
configurable: true ,
get: function() {
return name;
},
set: function(val) {
//呼叫處理函式
observer(name, val)
name = val;
}
});
targetObj.name = 'Martin';
targetObj.name = 'Lucas';
console.info('targetObj:', targetObj)
輸出結果為
...
name屬性的值從 Martin 改變為 Lucas
targetObj: {age: 1 , name: 'Lucas'}
...
ES6的實現
使用set方法實現
class TargetObj {
constructor(age, name) {
this.name = name;
this.age = age;
}
set name(val) {
observer(name, val);
name = val;
}
}
let targetObj = new TargetObj(1, 'Martin');
// 定義值改變時的處理函式
function observer(oldVal, newVal) {
// 其他處理邏輯...
console.info('name屬性的值從 '+ oldVal +' 改變為 ' + newVal);
}
targetObj.name = 'Lucas';
console.info(targetObj)
輸出結果為
...
name屬性的值從 Martin 改變為 Lucas
targetObj: {age: 1, name: 'Lucas'}
...
使用Reflect和Proxy實現
在ES6中新增的Proxy Api用處很多,結合Reflect Api可以方便的實現很多強大的邏輯,詳細介紹可以參見《ECMAScript 6 入門》—— 阮一峰 中的介紹。實現程式碼如下:
class TargetObj {
constructor(age, name) {
this.name = name;
this.age = age;
}
}
let targetObj = new TargetObj(1, 'Martin');
let observerProxy = new Proxy(targetObj, {
set(target, property, value, reciever) {
if (property === 'name') {
observer(target[property], value);
}
Reflect.set(target, property, value, reciever);
}
});
// 定義值改變時的處理函式
function observer(oldVal, newVal) {
// 其他處理邏輯...
console.info(`name屬性的值從 ${oldVal} 改變為 ${newVal}`);
}
observerProxy.name = 'Lucas';
console.info(targetObj);
輸出結果為
...
name屬性的值從 Martin 改變為 Lucas
targetObj: {age: 1, name: 'Lucas'}
...
總結
- ES6中很多的新增功能,都有效的提升了JS本身的合理性和高效性
- 很多基礎的方法,概念,雖然在做業務實現時使用較少,但是去了解其理念,對編碼思想的影響是很大的
- 觀察者模式可以很好的完成資料間的互動行為,雖然已經經常在用,但是具體瞭解後對整體的結構和原理有了更深層次的理解
- Proxy真的很好,很強大