2016-08-16 24 views
0

我正在代理一個數組,並根據某些條件修改數組來維護數據完整性,但是當數組從代理修改時,數組並沒有很好地放置。Javascript代理:修改數組目標和更新數組(長度,內容)

我遇到的問題是代理數組被*** undefined *** s污染。

如何修改目標對象以使其更正?

下面是一個示例筆:http://codepen.io/anon/pen/ZOPLZg(如果您查看控制檯,則空值實際上是未定義的值)。

在Chrome版本51.0.2704.103(64位)

var test = new Proxy([], { 
    set: function(target, name, value, receiver) { 
    if(name != 'length'){ 

     console.log(name, target) 

     // I want to overwrite values 
     var i = target.indexOf(value) 
     if(i > -1){ 
     // doesn't work 
     target.splice(parseInt(name, 10), 1); 

     // doesn't work 
     delete target[name]; 

     target[i] = value; 
     }else{ 
     target[name] = value; 
     } 
    }else{ 
     target[name] = value; 
    } 
    console.log(target); 
    return true; 
    } 
}); 

function log(){ 
    $('.log').append('<br/>' + JSON.stringify(test) + test.length); 
} 

log(); 
test.push('what', 'hi', 'yo'); 
log(); 
test.push('what', 'yo'); 
log(); 
test.splice(0, test.length) 
log(); 

這裏提交的錯誤工作 https://bugs.chromium.org/p/chromium/issues/detail?id=638414#

+0

目前尚不清楚你想要實現什麼。你說你想覆蓋註釋中的值,但是隻有當數組中的值在你想用相同的值覆蓋它時纔會覆蓋它。這不會使陣列保持不變。看起來你正在嘗試實現你自己的[Set](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set)或者其他的東西,但它不是很清楚。你想要輸出看起來像什麼? – Paulpro

+0

@Paulpro顯然,這只是用於演示數組添加「未定義」值的示例。在實踐中,這些想法是如果存在,則通過ID合併傳入的數據。沒有必要深入研究這個問題,因爲這個例子演示了「不變」數組是如何向數組中添加「未定義」值的。這個問題的目的是要問「爲什麼有未定義的值」或更好的「如何阻止它發生」。 –

+0

要回答你的問題,最終的數組應該是['what','hi','yo']。相反,它是['什麼','嗨','喲',未定義,未定義]。 –

回答

0
if (name != 'length') 
{ 
    // ... 
} else { 
    // Your trouble is the next line. Comment it to test 
    // But i don't understand why. 
    target[name] = value; 
} 
+0

啊!這樣做的工作.... execpt看到這個筆:http://codepen.io/anon/pen/YWgNdY使用拼接留下未定義的值在那裏....:headscratch: –

+0

請解釋你的代碼做什麼以及。這被認爲是一種好的做法。 –

+0

@VaibhavBajaj解釋代碼是很好的做法。但正如他所說,他不確定它爲什麼有效。他所說的是不做長度分配,只是返回true。 –

0

您的問題是一個事實,即Array.prototype.push設置length屬性來(see step 9),並且您的set函數將長度屬性的賦值作爲正常賦值處理。

一個可能的解決方案是隻允許分配到長度,如果他們不長的陣列過去的最後一個元素:

var test = new Proxy([], { 
    set: function(target, name, value, receiver) { 
    if(name != 'length'){ 

     // I want to overwrite values 
     if((i = target.indexOf(value)) > -1){ 
     target[i] = value; 
     }else{ 
     target[name] = value; 
     } 
    }else{ 
     if (value <= Math.max(-1, ... Object.keys(target)) + 1) 
     target.length = value; 
     numSkipped = 0; 
    } 

    return true; 
    } 
}); 
+0

嗨保羅,我曾嘗試在代碼庫中做這樣的事情,正如你所指出的那樣,然而,如果你拼接數組(未知數量的項目被刪除),我們再次陷入困境。見http://codepen.io/anon/pen/YWgNdY –

+0

@SenicaGonzalez我想出了另一種可能的解決方案(更新我的答案)。他們都有警告,就像這個不允許你手動設置長度到一個很大的值,如果這是你真正想要的,但我認爲它對你更好。 – Paulpro