1:什么是響應式❓
例子:let a = 1,b = 2;let c = a + b conosle.log(c) // => 3這個時候需要觸發c 返回 結果
改變 a 的值 再次打印c 才會顯示結果
響應式就是改變a的值,c就會自動改變結果
2:js中如何實現響應式❓
- 檢測其中某一個值是否發生變化
- 用跟蹤(track)函數修改值
- 用觸發(trigger)函數更新為最新的值
3:Vue是怎么實現響應式的?vue中如何跟蹤變化❓
vue中會用Object.defineProperty 的set,get方法處理遍歷所有的property並將其轉換為Proxy
為啥用Proxy?之前的不好嗎?
兩者的Surface Api 相同,但是Proxy 更簡單,同時提升了性能,代碼簡單它不香嗎?
提升了那些性能❓簡單了啥❓
Proxy 與 Object.defineProperty的對比 🤓
為啥還要defineProperty,不直接用Proxy❓
為了支持IE瀏覽器!!
Proxy 到底是啥❓
Proxy 是一個包含另一個對象或函數並允許你對其進行攔截的對象。 (vue官方說法)
或者就叫代理❓Proxy對象用於創建一個對象的代理,從而實現基本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數調用等)。(mdn說法)
1 const dinner = { 2 meal: 'tacos' 3 } 4 5 const handler = { 6 get(target, prop) { // target源對象 prop 對象的key 7 // 這里可以插一個攔截器 8 return target[prop] // 返回對應的value 9 } 10 } 11 12 const proxy = new Proxy(dinner, handler) 13 console.log(proxy.meal) 14 15 // tacos
Proxy提供了一個特性,不必這樣的返回target[prop],而是進一步使用Reflect方法。它允許我們正確的執行this綁定,比如
const dinner = { meal: 'tacos' } const handler = { get(target, prop, receiver) { // ...arguments => {meal: "tacos"} "meal" Proxy {meal: "tacos"} return Reflect.get(...arguments) } } const proxy = new Proxy(dinner, handler) console.log(proxy.meal) // tacos console.log(proxy) // Proxy {meal: "tacos"}
Reflect.get是啥❓
Reflect 是一個內置對象,它提供了攔截js 操作的方法
Reflect.get 獲取對象身上某個屬性的值,類似於target[name]
Reflect.get(target, propertyKey[, receiver])
target需要取值的目標對象
propertyKey需要獲取的值的鍵值
receiver如果target對象中指定了getter,receiver則為getter調用時的this值。
我們之前提到過,為了有一個 API 能夠在某些內容發生變化時更新最終值,我們必須在內容發生變化時設置新的值。我們在處理器,一個名為 track 的函數中執行此操作,該函數可以傳入 target 和 key 兩個參數。
const dinner = { meal: 'tacos' } const handler = { get(target, prop, receiver) { track(target, prop) // 這個玩意就是上面提到的 用跟蹤(track)函數修改值 return Reflect.get(...arguments) } } const proxy = new Proxy(dinner, handler) console.log(proxy.meal) // tacos
現在跟蹤函數也好了,該觸發(trigger)函數了
當某些內容發生改變時我們會設置新的值。為此,我們將通過觸發這些更改來設置新 Proxy 的更改:
const dinner = { meal: 'tacos' } const handler = { get(target, prop, receiver) { track(target, prop) // 跟蹤 key修改了值 return Reflect.get(...arguments) }, set(target, key, value, receiver) { trigger(target, key) // 觸發了,去改 key 的value return Reflect.set(...arguments) } } const proxy = new Proxy(dinner, handler) console.log(proxy.meal) // tacos
現在回頭看看
js中如何實現響應式的❓
- 檢測其中某一個值是否發生變化
- 用跟蹤(track)函數修改值
- 用觸發(trigger)函數更新為最新的值
Vue就是這么干的
- 當某個值發生變化時進行檢測:我們不再需要這樣做,因為 Proxy 允許我們攔截它
- 跟蹤更改它的函數:我們在 Proxy 中的 getter 中執行此操作,稱為
effect - 觸發函數以便它可以更新最終值:我們在 Proxy 中的 setter 中進行該操作,名為
trigger
