web-dev-qa-db-ja.com

なぜString(null)が機能するのですか?

nullおよびundefinedには、toStringまたはvalueOfメソッドがありません。 Stringを使用するAfaikは、パラメーターのtoStringメソッドを呼び出します(例:String({}) => _[object Object]_)。

なぜString(null)または_String(undefined_が機能するのですか?暗黙的にObject.prototype.toString.call(null)を行いません。これは_[object Null]_と評価されるためです。

[編集]:仕様ECMA-262/5版(48ページ)から。これは説明を追加するものではありません。

_/*
Table 13 — ToString Conversions  
-------------------------------------------------------------------------
Argument Type  | Result  
-------------------------------------------------------------------------
Undefined      | "undefined"
Null           | "null"  
Boolean        | If the argument is true, then the result is "true".
...            | ...
*/
_
23
KooiInc

以前の回答を確認したところ、私の以前の回答を完全に見直す必要があるようです。簡単に言えば、これらは標準仕様の特殊なケースであるということです。

仕様 for String()String関数として使用):

15.5.1.1文字列([値])

ToString(value)によって計算されたString値(Stringオブジェクトではない)を返します。値が指定されていない場合、空の文字列 ""が返されます。

ToString関数(ユーザーランドではなく内部に存在)は、次のように定義されます(9.8)。

「抽象操作ToStringは、表13に従って、引数をString型の値に変換します」

_Argument Type | Result
Null | "null"
Undefined | "undefined"
_

これは、String(null)およびString(undefined)がこの特別な型のテーブルに入り、_"null"_および_"undefined"_の値の文字列値を返すことを意味します。

ユーザーランドの疑似実装は次のようになります。

_function MyString(val) {
    if (arguments.length === 0) {
        return "";
    } else if (typeof val === "undefined") {
        return "undefined";
    } else if (val === null) {
        return "null";
    } else if (typeof val === "boolean") {
        return val ? "true" : "false";
    } else if (typeof val === "number") {
        // super complex rules
    } else if (typeof val === "string") {
        return val;
    } else {
        // return MyString(ToPrimitive(val, prefer string))
    }
}
_

(この例では、コンストラクターのケース(new MyString())を無視し、エンジンランドではなくユーザーランドの概念を使用していることに注意してください。)


私は少し夢中になり、実装例(具体的にはV8)を見つけました:

_string.js:_

_// Set the String function and constructor.
%SetCode($String, function(x) {
  var value = %_ArgumentsLength() == 0 ? '' : TO_STRING_INLINE(x);
  if (%_IsConstructCall()) {
    %_SetValueOf(this, value);
  } else {
    return value;
  }
});
_

_macros.py:_

_macro TO_STRING_INLINE(arg) = (IS_STRING(%IS_VAR(arg)) ? arg : NonStringToString(arg));
_

_runtime.js:_

_function NonStringToString(x) {
  if (IS_NUMBER(x)) return %_NumberToString(x);
  if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
  if (IS_UNDEFINED(x)) return 'undefined';
  return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
}
_

NonStringToString(本質的に興味深いもの)は、psuedo-JS-landで幸運にも定義されています。ご覧のとおり、null/true/false/undefinedの特別なケースがあります。

30
Corbin

おそらく、nullundefinedのような特別な場合のための追加のチェックと処理がいくつかあります。

MDNによると

「安全な」toStringの代替としてStringを使用することは可能です。それでも、通常は基礎となるtoStringを呼び出しますが、nullおよび未定義に対しても機能します。

2
Thilo

Annotated ES5 (ECMAScript 5 PDFよりもはるかに読みやすい)の表示に興味があるかもしれません。 new String([ value ])http://es5.github.com/#x15.5.2.1 呼び出し[ToString]http://es5.github.com/#x9.8 (特別な変換ケースの表があります)渡された値を文字列に変換します。

1
Dan D.

String(null)は、文字列オブジェクトを作成して、デフォルト値のnullを渡します。

0
robrich