成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

記一次思否問答的問題思考:Vue為什么不能檢測數組變動

raoyi / 1021人閱讀

摘要:這里加了個簡單判斷,只看數組元素的,然后寫了一個簡單案例,主要測試使用改變數組元素能不能被監(jiān)測到,并響應式的渲染頁面運行頁面可以看到,運行了次,我們數組長度為,也就是說數組被遍歷了兩遍。

問題來源:https://segmentfault.com/q/10...

問題描述:Vue檢測數據的變動是通過Object.defineProperty實現的,所以無法監(jiān)聽數組的添加操作是可以理解的,因為是在構造函數中就已經為所有屬性做了這個檢測綁定操作。

但是官方的原文:由于 JavaScript 的限制, Vue 不能檢測以下變動的數組:

當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如: vm.items.length = newLength

這句話是什么意思?我測試了下Object.defineProperty是可以通過索引屬性來設置屬性的訪問器屬性的,那為何做不了監(jiān)聽?

有些論壇上的人說因為數組長度是可變的,即使長度為5,但是未必有索引4,我就想問問這個答案哪里來的,修改length,新增的元素會被添加到最后,它的值為undefined,通過索引一樣可以獲取他們的值,怎么就叫做“未必有索引4”了呢?

既然知道數組的長度為何不能遍歷所有元素并通過索引這個屬性全部添加set和get不就可以同時更新視圖了嗎?

如果非要說的話,考慮到性能的問題,假設元素內容只有4個有意義的值,但是長度確實1000,我們不可能為1000個元素做檢測操作。但是官方說的由于JS限制,我想知道這個限制是什么內容?各位大大幫我解決下這個問題,感謝萬分

面對這個問題,我想說的是,首先,長度為1000,但只有4個元素的數組并不一定會影響性能,因為js中對數據的遍歷除了for循環(huán)還有forEach、map、filter、some等,除了for循環(huán)外(for,for...of),其他的遍歷都是對鍵值的遍歷,也就是除了那四個元素外的空位并不會進行遍歷(執(zhí)行回調),所以也就不會造成性能損耗,因為循環(huán)體中沒有操作的話,所帶來的性能影響可以忽略不計,下面是長度為10000,但只有兩個元素的數組分別使用for及forEach遍歷的結果:

var arr = [1]; arr[10000] = 1
function a(){
    console.time()
    for(var i = 0;i{console.log(2)})
    console.timeEnd()
}
b(); //default: 0.81982421875ms
b(); //default: 0.434814453125ms

可以看到結果非常明顯,不過,如果for循環(huán)中不做操作的話兩者速度差不多

其次,我要說的是,我也不知道這個限制是什么 ???? (????) ???? ╮( ??ω?? )╭

Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 并返回這個對象。數組的索引也是屬性,所以我們是可以監(jiān)聽到數組元素的變化的

var arr = [1,2,3,4]
arr.forEach((item,index)=>{
    Object.defineProperty(arr,index,{
        set:function(val){
            console.log("set")
            item = val
        },
        get:function(val){
            console.log("get")
            return item
        }
    })
})
arr[1]; // get  2
arr[1] = 1; // set  1

但是我們新增一個元素,就不會觸發(fā)監(jiān)聽事件,因為這個新屬性我們并沒有監(jiān)聽,刪除一個屬性也是。

再回到題主的問題,既然數組是可以被監(jiān)聽的,那為什么vue不能檢測vm.items[indexOfItem] = newValue導致的數組元素改變呢,哪怕這個下標所對應的元素是存在的,且被監(jiān)聽了的?

為了搞清楚這個問題,我用vue的源碼測試了下,下面是vue對數據監(jiān)測的源碼:

可以看到,當數據是數組時,會停止對數據屬性的監(jiān)測,我們修改一下源碼:

使數據為數組時,依然監(jiān)測其屬性,然后在defineReactive函數中的get,set打印一些東西,方便我們知道調用了get以及set。這里加了個簡單判斷,只看數組元素的get,set

然后寫了一個簡單案例,主要測試使用vm.items[indexOfItem] = newValue改變數組元素能不能被監(jiān)測到,并響應式的渲染頁面

運行頁面

可以看到,運行了6次get,我們數組長度為3,也就是說數組被遍歷了兩遍。兩遍不多,頁面渲染一次,可能多次觸發(fā)一個數據的監(jiān)聽事件,哪怕這個數據只用了一次,具體的需要看尤大代碼怎么寫的。就拿這個來說,當監(jiān)聽的數據為數組時,會運行dependArray函數(代碼在上面圖中get的實現里),這個函數里對數組進行了遍歷取值操作,所以會多3遍get,這里主要是vue對data中arr數組的監(jiān)聽觸發(fā)了dependArray函數。

當我們點擊其中一個元素的時候,比如我點擊的是3

可以看到會先運行一次set,然后數據更新,重新渲染頁面,數組又是被遍歷了兩遍。

但是!?。到M確實變成響應式的了,也就是說js語法功能并不會限制數組的監(jiān)測。

這里我們是用長度為3的數組測試的,當我把數組長度增加到9時

可以看到,運行了18次get,數組還是被遍歷了兩遍,點擊某個元素同理,渲染的時候也是被遍歷兩次。

有了上面的實驗,我的結論是數組在vue中是可以實現響應式更新的,但是不明白尤大是出于什么考慮,沒有加入這一功能,希望有知道的大佬們不吝賜教

2018-07-27補充

github上提問了尤大

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/96307.html

相關文章

  • 【半月刊 4】前端高頻面試題及答案匯總

    摘要:引言半月刊第四期來啦,這段時間新增了道高頻面試題,今天就把最近半月匯總的面試題和部分答案發(fā)給大家,幫助大家查漏補缺,歡迎加群互相學習。更多更全的面試題和答案匯總在下面的項目中,點擊查看。引言 半月刊第四期來啦,這段時間 Daily-Interview-Question 新增了 14 道高頻面試題,今天就把最近半月匯總的面試題和部分答案發(fā)給大家,幫助大家查漏補缺,歡迎 加群 互相學習。 更多更...

    hankkin 評論0 收藏0
  • 一次XX前端面試

    摘要:面試官說那我問你一個哲學的問題,為什么有數據結構這種東西哇,這是啥,巴拉巴拉扯了一通,大致就是物以類聚,人以群分,先人積累下來的經驗,這些讓我們更方便處理數據啥的。 前因,沒有比摸魚有趣的事了 距離自己被外派(俗稱外包)出去,已經過了快五個月,工作的話,很閑。人啊,一定保持好的習慣,懶惰是會上癮,日常摸魚,懷疑人生,我是誰,我在哪,我要干什么。 中午吃飯的時候,收到了boss直聘的一條...

    Shisui 評論0 收藏0
  • 使用Vue渲染可配置表單--一次問卷平臺項目

    摘要:相當于可以編輯問卷并提供問卷展示,數據統(tǒng)計的這么一個平臺。極大的節(jié)省了需要進行表單樣式修改的時間,同時,讓動態(tài)渲染表單成為一件可能且容易的事情。表單動態(tài)渲染剛好在項目之前,有過一次動態(tài)配置表單的嘗試通過字段自動生成表單及驗證。 近幾天來了個緊急項目,想要做一個內部版本的問卷星。相當于可以編輯問卷并提供問卷展示,數據統(tǒng)計的這么一個平臺。整個項目耗時不長,本著積淀和積累的原則,將過程中的...

    mcterry 評論0 收藏0
  • 記錄vue不能檢測數組和對象變動方法。

    摘要:當然按照官方文檔的解釋,檢測不到的主要問題是導致的。下列代碼,是解決數組檢測不到的問題。 測試數據: items: [ {name: 業(yè)務狀態(tài), id: taskState, data: [{name:全部, id: 0},{name:進行中, id: 1},{name:已完成, id: 2},{name:已歸檔, id: 3},{name:已終止, id: 4}]}, ...

    Clect 評論0 收藏0

發(fā)表評論

0條評論

raoyi

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<