4

編集:全員のフィードバックに基づいて、この質問の元のバージョンは、標準に関連するものではなく、設計に関連するものです。より SO フレンドリーに。


オリジナル:

JS プリミティブは、ECMA 標準に従って、そのプリミティブのオブジェクト ラップ バージョンと「同等」と見なされるべきですか?


改訂された質問

現在の JavaScript でプリミティブにラップされたオブジェクトを比較する方法について、普遍的な合意はありますか?

var n = new Number(1),
    p = 1;
n === p;     // false
typeof n;    // "object"
typeof p;    // "number"
+n === p;    // true, but you need coercion.

編集:

@Pointy がコメントしたように、ECMA 仕様 (262、S15.1.2.4)にはNumber.isNaN()、次のように動作するメソッドが記述されています。

Number.isNaN(NaN);                // true
Number.isNaN(new Number(NaN));    // false
Number.isNaN(+(new Number(NaN))); // true, but you need coercion.

どうやら、この動作の正当な理由は、IF the argument coerces toisNaNを返すことです。ネイティブの操作方法に基づいて直接強制することはありません。trueNaNnew Number(NaN)isNaN

現時点では、プリミティブではなくネイティブ オブジェクト ラッパーを直接使用することによるパフォーマンス ヒットや型変換などのトリッキーさが、セマンティックなメリットを上回っているようです。

この JSPerf を参照してください。

4

1 に答える 1

2

あなたの質問に対する簡単な答えはノーです。質問が状況的すぎるため、JSで値を比較する方法についてのコンセンサスはありません。それはあなたの特定の状況に大きく依存します。

しかし、いくつかのアドバイスを与える/より長い答えを提供するために....プリミティブのオブジェクトバージョンは悪であり(「道徳的な意味ではなく、多くのバグの意味を引き起こす」)、可能であれば避ける必要があります。したがって、両方を処理するやむを得ない理由がない限り、オブジェクトでラップされたプリミティブを考慮せず、コード内でラップされていないプリミティブに固執することをお勧めします。

さらに、ラップされたプリミティブを考慮しない場合は、そもそもequalsメソッドを使用する必要がなくなるはずです。

*編集*

あなたの最新のコメントを見たばかりです。配列を比較する必要がある場合は、組み込みで==あり、===それをカットしません。それでも、関数をできるだけ集中させ、組み込みのJSコンパレータをできるだけ使用することで、多くのドラマを回避できるため、arrayEquals単なるメソッドではなくメソッドを作成することをお勧めします。equals

そして、それをある種の一般的な関数でラップする場合は、便宜上、次のようにします。

function equals(left, right) {
    if (left.slice && right.slice) { // lame array check
        return arrayEquals(left, right);
    }
    return left == right;
}

「処理」によって、プリミティブでラップされたオブジェクトが渡された場合に関数がエラーをスローしない限り、プリミティブでラップされたオブジェクトを処理しないことをお勧めします。繰り返しになりますが、これらのオブジェクトは問題を引き起こすだけなので、できるだけ回避するように努め、悪いコードを導入するための開口部を残さないようにする必要があります。

于 2013-01-02T21:15:32.443 に答える