響應(yīng)式框架原理3(Object.defineProperty VS Proxy)

響應(yīng)式框架原理2(數(shù)據(jù)劫持與代理-監(jiān)聽數(shù)組變化)
繼續(xù)之前的記錄、、
使用 Proxy 來完成代碼重構(gòu):

            let data = {
                stage: '狀態(tài)',
                course: {
                    title: '標題',
                    author: ['作者1', '作者2'],
                    publishTime: '出版時間'
                }
            }

            const observe = data => {
                if (!data || Object.prototype.toString.call(data) !== '[object Object]') {
                    return
                }

                Object.keys(data).forEach(key => {
                    let currentValue = data[key]
                    // proxy 也可以對函數(shù)類型進行代理。這里只對承載數(shù)據(jù)類型的 object 進行處理
                    if (typeof currentValue === 'object') {
                        observe(currentValue)
                        data[key] = new Proxy(currentValue, {
                            set(target, property, value, receiver) {
                                // 因為數(shù)組的 push 會引起 length 屬性的變化,所以 push 之后會觸發(fā)兩次 set 操作,只需要保留一次即可,property 為 length 時,忽略
                                if (property !== 'length') {
                                    console.log(`setting ${key} value now, setting value is`, currentValue)
                                }
                                return Reflect.set(target, property, value, receiver)
                            }
                        })
                    } else {
                        Object.defineProperty(data, key, {
                            enumerable: true,
                            configurable: false,
                            get() {
                                console.log(`getting ${key} value now, getting value is:`, currentValue)
                                return currentValue
                            },
                            set(newValue) {
                                currentValue = newValue
                                console.log(`setting ${key} value now, setting value is`, currentValue)
                            }
                        })
                    }
                })
            }
            observe(data)

對數(shù)組操作:

            data.course.author.push('作者3')

上面代碼在使用proxy進行代理時,并沒有對getter進行代理,所以輸出結(jié)果不會有g(shù)etting value輸出
使用 Object.defineProperty;對于鍵值為對象類型的情況,繼續(xù)遞歸調(diào)用 observe 方法,并通過 Proxy 返回的新對象對 data[key] 重新賦值,這個新值的 getter 和 setter 已經(jīng)被添加了代理。

結(jié)合上兩篇筆記,對 Proxy 實現(xiàn)數(shù)據(jù)代理和 Object.defineProperty 實現(xiàn)數(shù)據(jù)攔截進行對比:

  • Object.defineProperty 不能監(jiān)聽數(shù)組的變化,需要進行數(shù)組方法的重寫

  • Object.defineProperty 必須遍歷對象的每個屬性,且對于嵌套結(jié)構(gòu)需要深層遍歷

  • Proxy 的代理是針對整個對象的,而不是對象的某個屬性,因此不同于 Object.defineProperty 的必須遍歷對象每個屬性,Proxy 只需要做一層代理就可以監(jiān)聽同級結(jié)構(gòu)下的所有屬性變化,當然對于深層結(jié)構(gòu),遞歸還是需要進行的

  • Proxy 支持代理數(shù)組的變化

  • Proxy 的第二個參數(shù)除了 set 和 get 以外,可以有 13 種攔截方法,比起 Object.defineProperty() 更加強大 Proxy與Reflect

  • Proxy 性能將會被底層持續(xù)優(yōu)化,而 Object.defineProperty 已經(jīng)不再是優(yōu)化重點

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容