以前の回答を確認した後、以前の回答を完全に見直す必要があるようです。簡単に言えば、これらは標準仕様の特殊なケースであるため、私はそれを複雑にしすぎていました。
(関数として使用される)の仕様:String()
String
15.5.1.1 文字列 ([値])
ToString(value) によって計算された文字列値 (文字列オブジェクトではない) を返します。値が指定されていない場合は、空の文字列 "" が返されます。
関数(ToString
ユーザーランドではなく、内部に存在する) は次のように定義されます (9.8):
「抽象操作 ToString は、表 13 に従って、その引数を String 型の値に変換します」
Argument Type | Result
Null | "null"
Undefined | "undefined"
これは、String(null)
この特別なタイプのテーブルに移動し、値がandString(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 (これは基本的に興味深いものです) は、幸いにも puedo-JS-land で定義されています。ご覧のとおり、実際には null/true/false/undefined の特殊なケースがあります。