Просмотрев мой предыдущий ответ, кажется, полный пересмотр моего предыдущего ответа необходимо. Я немного усложнил это, так как короткий ответ заключается в том, что это специальные случаи, определенные стандартами.
specification для String()
(String
используется в качестве функции):
15.5.1.1 Строка ([значение])
Возвращает значение String (не объект String), вычисленную ToString (значение). Если значение не указано>, возвращается пустая строка "".
ToString
функция (которая существует внутри, не в пространстве пользователя) определяется следующим образом (9.8):
«Абстрактная операция ToString преобразует свой аргумент в значение типа String, в соответствии с таблицей 13»
Argument Type | Result
Null | "null"
Undefined | "undefined"
Это означает, что String(null)
и String(undefined)
идти в эту специальную таблицу типов и просто возвращают строковые значения на сумму "null"
и "undefined"
.
Пользовательской земля псевдо-реализация выглядит следующим образом: (. Обратите внимание, что этот пример игнорирует случай конструктора (new MyString()
), и что он использует пользователь землю концепцию, а не двигатель-землю)
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))
}
}
я получил немного увлеклись и нашел пример реализации (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 (который является по существу то, что представляет интерес), к счастью, это определено в псевдо-JS-земли. Как вы можете видеть, действительно существует специальный случай для null/true/false/undefined.
Спасибо за ваш ответ Корбин, это ясно. – KooiInc
@Kooilnc Нет проблем. – Corbin
String()! == String (undefined) - это потому, что в JavaScript два объекта равны, только если они являются одним и тем же объектом в памяти. При вызове String() вы создаете объект-оболочку вокруг примитива строки, поэтому по существу сравнение состоит из двух разных объектов, обертывающих один и тот же примитив строки. – Buzzy