1

私は最近、JS 配列プロトタイプにいくつかの拡張機能を書きました。

Array.prototype.diff = function (a) {
    return this.filter(function (i) {
        return !(a.indexOf(i) > -1);
    });
};

Array.prototype.udiff = function (a, b) {
    var rslt = this.concat(b);
    return rslt.filter(function (i) {
        return !(a.indexOf(i) > -1);
    });
};

そこには何もひどく刺激的ではありません。しかし、その後、私は非常に珍しいことに遭遇しました。ここに例があります

var arr = [];
for (prop in arr) {
    arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
}

非常に無害に見えるコードですが、「未定義にはメソッドreplaceAllがありません-replaceAllは私自身のString.prototype拡張です.

解決策は簡単です - arr[prop] を操作する前に発行するだけです

if ('string' == typeof(prop)) continue;

その理由は、 prop もdiffまたはudiffになる可能性があるためです。それで、問題は解決しましたが、この振る舞いは私を油断させ、追加の typeof テストを行わなければならないのは不器用に聞こえます。おそらく、ここにいる誰かが、プロトタイプ拡張機能で何が起こるかについて、より深い洞察を持っているでしょうか?

これらの問題はすべて、Windows 上の Chrome で発生したことに注意してください。

4

2 に答える 2

2

詳細な説明については、この回答を参照してください


問題は解決しましたが、この動作は私を油断させ、追加の typeof テストを実行する必要があるのは不器用に聞こえます。

適切な方法は、配列にループを使用するのではなく、for inそれらの長さまで反復することです。

for (var i=0; i<arr.length; i++) {
    arr[i].attrib = arr[i].attrib.replaceAll('_', ' ', true);
}
于 2013-09-06T13:33:30.560 に答える
0

JavaScript の for each ループは、オブジェクト内のすべてのシンボル (プロトタイプ内のシンボルを含む) を反復処理します。それがあなたがした結果を得た理由です。hasOwnProperty()これが、関数を常にfor each ループと組み合わせて使用​​する必要がある理由でもあります。

var arr = [];
for (prop in arr) {
    if(arr.hasOwnProperty(prop)) {
        arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
    }
}
于 2013-09-06T12:52:30.973 に答える