javascript
javascript --- vue2.x中原型的使用(拦截数组方法) 响应式原理(部分)
說明
在Vue2.x中,利用了對原型鏈的理解,巧妙的利用JavaScript中的原型鏈,實現(xiàn)了數(shù)組的pop、push、shift、unshift、reverse、sort、splice等的攔截.
你可能需要的知識
- 參考 - MDN
原型鏈
JavaScript常被描述為一種基于原型的語言(prototype-based language),每個對象擁有一個原型.
數(shù)組類型也不例外.驗證如下:
可見數(shù)組的原型是繼承于Object。
響應式
參考 - MDN
響應式的核心是使用Object.defineProperty在對數(shù)據(jù)進行讀取或者寫入時進行劫持操作.
對一個屬性,同時使用get和set方法時,需要一個中間變量取存儲,否則會造成循環(huán)使用.
Vue 2.x中的響應式
- Vue在使用過程中,可能會用到很多的變量,而每把一個數(shù)據(jù)進行響應式化,就需要一個變量去存儲.這樣有可能會污染全局作用域.
- Vue中采取的方法是使用函數(shù)的形參,來實現(xiàn)響應式,實現(xiàn)如下
以上實現(xiàn)了對數(shù)據(jù)的攔截: 即對數(shù)據(jù)進行 寫入/讀取 操作時,會按照一定規(guī)則優(yōu)先執(zhí)行某些步驟.
但是以上代碼還存在一些小小的瑕疵
對象深層次
以上代碼不對對象的深層次進行響應式化,如下面數(shù)據(jù)
let o = {list: [ { person1: {name:'Marron',age: 18}},{person2: {name:'Mar',age: 25}}] }
此時,需要考慮數(shù)組,和對象的子元素問題.
對于數(shù)組問題,我們修改遍歷,如果是數(shù)組,則取出數(shù)組中的每個元素,進行添加響應式處理
對于深層次對象問題,我們對defineReactive進行修改
function defineReactive(o, key, value, enumerable){if(typeof value =='object' && value !== null && !Array.isArray(value)){// 此處可以認為是對象reactify(value)}// 此處是最后一層,添加響應式Object.defineProperty(o, key, {configurable: true,enumerable: !!enumerable,get(){console.log(`讀取${key}`)return value},set(newVal){console.log(`寫入${key} => ${newVal}`)value = newVal}}) }Vue2.x對數(shù)組部分方法的攔截
上面的響應式無法對數(shù)組的pop、push等方法進行響應
在Vue2.x中,使用了修改原型鏈的結構的方式來對數(shù)組的變化進行攔截.
先看下面的關系
- 原本的關系圖示已經(jīng)描述的很清楚了
- 我們對pop和push的攔截的原理
- 實際上是對Array原型上的pop、push方法進行重寫
- 但是我們不可能直接在這個原型上重寫(因為有些數(shù)組的實例,并不需要響應式).
- 因此我們在arr和Array.prototype之間添加一層arr_methods,改進后的關系如下
【具體的實現(xiàn)思路】:
先創(chuàng)建一個arr_methods對象其原型是Array.prototype.然后修改arr_methods上需要攔截的方法(存儲在數(shù)組ARRAY_METHOD中)
此時既不影響原生的Array.prototype,又實現(xiàn)了對pop、push...方法的攔截,完成之后只需要修改前面的方法.即可完成對數(shù)組pop、push方法的攔截
最后,此時只是攔截,還差一步形成響應式
ARRAY_METHOD.forEach(method=>{arr_methods[method] = function(){// 攔截的函數(shù)console.log(`調用${method}方法`)for(let i =0, len = arugments.length; i < len; i++){reactify(arguments[i])}return Array.prototype[method].apply(this, arguments)} })總結
以上是生活随笔為你收集整理的javascript --- vue2.x中原型的使用(拦截数组方法) 响应式原理(部分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西南科技大学 SWUST OJ系统942
- 下一篇: 文档根元素 project 必须匹配 d