2016-08-16 17 views
0

データの整合性を維持するために配列をプロキシしていくつかの条件に基づいて配列を変更していますが、Javascriptプロキシ:配列のターゲットを変更して配列(長さ、内容)を更新する

私が経験している問題は、プロキシ配列が***未定義の状態で汚染されていることです。

ターゲットオブジェクトを変更した場合、それをどのようにして更新しますか?

ペンの例を以下に示します:http://codepen.io/anon/pen/ZOPLZg(実際にはコンソールを見るとヌル値は未定義です)。

クロームバージョン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']でなければなりません。代わりに['what'、 'hi'、 'yo'、undefined、undefined]です。 –

答えて

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コードを説明することをお勧めします。しかし、彼が言ったように、彼は本当になぜそれが動作するか分からない。彼が言っているのは、長さの割り当てをしないで、ただ真実に戻すことです。 –

0

あなたの問題はArray.prototype.pushがlengthプロパティを設定しているという事実から来ています(see step 9)を使用し、set関数はlengthプロパティへの代入を通常の代入として処理します。

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

関連する問題