3

Object.prototype.toString.call(anything)結果は常にです。これは、いくつかのことの1つ[object Something]である可能性がありますSomething。私の質問は、なぜ「オブジェクト」の部分がそこにあるのかということです。いつもそこにあるのは不必要に思えます。渡された引数については何も教えてくれません。

Object.prototype.toString.call(null);
=> [object Null]

Object.prototype.toString.call(undefined);
=> [object Undefined]

nullundefinedはオブジェクトではない(そして失敗する)のでCheckObjectCoercible、「オブジェクト」の部分は実際には無意味に見えます。

もともと「オブジェ」の部分がそこに置かれたのには、それ以来その理由が失われていたとしても、何らかの理由があったと思いますが、今では歴史的な理由で保存されています。

誰かがこれに光を当てるのを手伝ってもらえますか?


明確にするために、私はオブジェクトObject.prototype.toStringの(タイプ)を取得するためにどのように使用できるかをすでに知っています。[[Class]]私の質問は、返される文字列の形式の理由、特に最初の「オブジェクト」部分に関するものです。この部分に理由があったかどうか、またはこの部分に将来の理由があるかどうかを知りたいです。将来的には「オブジェクト」以外のものを返す可能性がありますか?常に「オブジェクト」を返すことを期待できますか?もしそうなら、なぜそれはそれを返すのですか?入力が何であっても、関数が常に同じものを返すことを望むのは誰ですか?

4

3 に答える 3

3

ES5.1仕様のAnnexFは、次のことについて述べていObject.prototype.toStringます。

15.2.4.2:Edition 5は、この値が既存のコードの失敗を引き起こしたため、undefinedとnullを処理します。このようなコードとの互換性を維持するために仕様が変更されました。新しいステップ1と2がアルゴリズムに追加されました。

これは、ES5.1仕様で行われた修正です。ES5より前は、nullまたはundefinedをtoStringに渡すと、常にグローバルオブジェクトが代わりに渡されていました。ES5での厳密なモード関連の変更により、nullおよびundefinedが変更なしで渡されます。ES5で指定されているように、nullまたはundefinedを渡すObject.prototype.toStringと、TypeError例外が発生しました。この例外はいくつかの既存のコードを壊したので、その場合にスローされないように仕様を修正する必要がありました。

toStringでは、nullおよびundefinedに対して何を返す必要がありますか?既存のコードの多くはObject.prototype.toString、常にフォームの文字列を返すことも期待していることがわかりました"[object *]"。そこで、nullと未定義のプロデュース"[object Null]"とを作成することにし"[object Undefined]"ました。

これは機能していたようで、ES5 / 5.1の厳密なモード関連の変更が存在する場合でも、既存のES3ベースのコードが機能し続けることが一般的に許可されています。

于 2012-11-01T06:05:50.457 に答える
2

さて、このように考えてください:

  1. JavaScriptのすべての値は、実際にはクラスのインスタンスです。とさえundefinednullインタプリタでシングルトンオブジェクトとして実装されます。たとえば、undefined実際Undefined.instanceにはRhino(Javaで実装)にあります。
  2. 定義されたtoStringメソッドは、JavaScript値のクラス名を公開します。ただし、値はクラス自体ではなくクラスのインスタンスであるためtoString、の形式の文字列を返します[object ClassName]
  3. はい、[object *]フォームは冗長です。しかし、誰かがそれをそのようにしたかったので、私たちはそれに固執しています。そこにあるので、突然変更すると多くの問題が発生します。それに依存する古いコードは壊れることがあります。

編集: JavaScriptが終了し、インタプリタが開始するタイミングに注意することが重要です。たとえば、JavaScriptで関数を呼び出すと、インタープリターは新しい実行コンテキストを作成します。これは、JavaScriptインタープリターが記述されている言語のオブジェクトです(JavaScript自体ではありません)。

同様に、[[Class]]JavaScript値のは、JavaScriptインタープリターが記述されている言語のクラスであり、そのクラスのインスタンスを作成するために使用されます。たとえば、Rhinoでは、関数はクラスのインスタンスですorg.mozilla.javascript.BaseFunction。このクラスには、 (のインスタンスの)getClassName返す というメソッドがあります。Function[[Class]]BaseFunction

同様に、のシングルトンインスタンスであるorg.mozilla.javascript.Undefinedという静的プロパティを持つというクラスがあります。instanceUndefined

于 2012-10-31T05:49:12.950 に答える
1

ES5の内容は次のとおりです。

15.2.4.2 Object.prototype.toString()

toStringメソッドが呼び出されると、次の手順が実行されます。

  1. この値が未定義の場合は、「[objectUndefined]」を返します。
  2. この値がnullの場合、「[objectNull]」を返します。
  3. この値を引数として渡してToObjectを呼び出した結果をOとします。
  4. classをOの[[Class]]内部プロパティの値とします。
  5. 3つの文字列"[object"、class、および"]"を連結した結果であるString値を返します。

したがって、toString最初にとを処理しundefinednull次に引数をオブジェクトに変換してから、[[Class]]そのオブジェクトの内部プロパティを返します。toStringこれはオブジェクトに継承されることを目的としているため、そのように動作するのは公正なことであることに注意してください。

ECMAScriptでは、すべてがオブジェクトです。プリミティブは、次のようなことを避けるための便利な機能です。

// Create number objects with the same value
var a = new Number(7);
var b = new Number(7);

a == b; // false

a.valueOf() == b.valueOf(); // true

JavaScriptの主な目標は、シンプルにすることでした。ゆるい型付けは人生を楽にしますが、それはまた学ぶべきいくつかの失敗があることを意味します。

于 2012-10-31T07:11:40.013 に答える