3

序章

argumentsJavaScript 関数のこれらのばかげたオブジェクトについては、誰もが知っています。

しかし、なぜ反対するのですか?配列じゃない?

いいえ、そうではありません。そのため、多くの人が JavaScript の概念の失敗と呼んでいます。

(function () {
    return arguments.slice(); // TypeError: arguments.slice is not a function
}());

目的

わかりました、これは私が聞きたいことの紹介にすぎませんが、質問する前に、さらに情報が必要です。

ここ数日、さまざまなコードを読んでいるうちに、次のコード行がかなりの場所にあるのを見て、かなり怖くなってきました。

args = Array.prototype.slice(arguments);

argumentsしたがって、それが行うことは、オブジェクトをすべてのプロトタイプとものを含む配列に単純に「変換」することです。


私の解決策

私が考えたのは次のことでした: JavaScript はプロトタイピングがすべてですが、argumentsオブジェクトprototype自体を拡張してみませんか? いくつかのサイトで既存のスクリプトを確認しましたが、見つけようとしていたものは何も見つからず、最終的に自分で作成することになりました。

(function () {
    var i, methods;

    arguments.constructor.prototype = Array.prototype;
    methods = ['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'slice', 'sort', 'splice', 'toString', 'unshift'];

    for (i = 0; i < methods.length; i += 1) {
        if (arguments.constructor.prototype.hasOwnProperty(methods[i]) === false) {
            arguments.constructor.prototype[methods[i]] = Array.prototype[methods[i]];
        }
    }
}());

圧縮後は 260 バイトしかなく、を使用してargumentsオブジェクトを拡張します。prototypeArray.prototype

最終的にarguments、「実際の」配列と同じようにオブジェクトを処理できるようになりました。


質問

最も有名な JavaScript フレームワークをチェックした後、私は次のように仕上げましargumentsprototype

しかし、なぜ?何か問題がありますか、私は今考えていませんか?

4

3 に答える 3

5

argumentsオブジェクトはタイプではなく、ジェネリックですObject。プロトタイプを拡張するには、 のプロトタイプを拡張する必要がありますがObject、これは一般的には良い考えではありません。

argumentsを使用して配列に変換しても問題はありませんArray.prototype.slice

argumentsプロトタイプを拡張するとしましょう:

arguments.constructor.prototype.foo = 'bar';

ここでの問題は、オブジェクトでarguments.constructorはなく、ただの. 今、正常に動作するはずのことをしようとすると、それは失敗します:ArgumentObject

var someNewObject = {
    someProperty: 'someValue'
};

for (var item in someNewObject) {
    console.log(item);  // logs someProperty AND foo, not good
}

ここで実際にこれを見ることができます

于 2012-08-07T17:40:11.773 に答える
2

一般に、ほとんどの人は ECMAScript/JavaScript ネイティブ オブジェクトを変更することをためらいます。個人的には、あなたのアプローチが気に入っています (巧妙で便利です)。ただし、コードを大規模なプロジェクトに導入すると、問題が発生します。ブラウザーの Array (ネイティブ) オブジェクトの実装が標準と異なり、他のコード ライブラリ (jQuery など) が特定の期待を持ってそれを処理する場合、意図しない結果が生じる可能性があります。ただし、jQuery が関数の引数プロパティ (/object) が特定の型であると想定し、たとえばコードによって変更されている場合、jQuery のような広く使用されているライブラリが壊れる可能性があります。

于 2012-08-07T17:37:44.010 に答える
0

それは機能しますか?;-)

もしそうなら、あなたはあなたが望んでいたことを達成したと思います。ただし、引数が配列でない理由の 1 つは、arguments 変数が通常の変数のように移動することを意図していない可能性があります。関数本体内でのみアクセスしてから破棄することを意図しています。したがって、突然配列なったときに何が起こるかわかりません。

それ以外は、賢い解決策です!

于 2012-08-07T17:39:57.700 に答える