Después de revisar mi respuesta anterior, parece una revisión completa de mi respuesta anterior es necesario. Me estaba complicando demasiado, ya que la respuesta corta es que estos son casos especiales especificados en estándares.
El specification para String()
(String
utilizado como una función):
15.5.1.1 String ([valor])
Devuelve un valor String (no un objeto String) calculada por ToString (valor) Si el valor no se> proporciona, se devuelve la cadena vacía "".
La función ToString
(que existe internamente, no en espacio de usuario) se define como sigue (9,8):
"El ToString operación abstracta convierte su argumento a un valor de tipo String acuerdo con la Tabla 13"
Argument Type | Result
Null | "null"
Undefined | "undefined"
esto significa que String(null)
y String(undefined)
entran en esta tabla especial de tipos y simplemente volver a los valores de la cadena de valor "null"
y "undefined"
.
Un pseudo-aplicación fácil de la tierra es como la siguiente: (. Tenga en cuenta que este ejemplo ignora el caso constructor (new MyString()
) y que utiliza los conceptos de zona de usuario en lugar de motor de la tierra)
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))
}
}
me llevar un poco y encontré un ejemplo de implementación (V8 para ser específicos):
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));
}
El NonStringToString (que es esencialmente lo que es de interés), se define por suerte en psuedo-JS-tierra. Como puede ver, de hecho hay un caso especial para null/true/false/undefined.
Gracias por su respuesta Corbin, está claro. – KooiInc
@Kooilnc No hay problema. – Corbin
String()! == String (undefined) es porque en JavaScript dos objetos son iguales solo si son el mismo objeto en la memoria. Cuando se llama a String(), se está creando un objeto envoltorio alrededor de la primitiva de cadena, por lo que esencialmente la comparación es de dos objetos diferentes que envuelven la misma primitiva de cadena. – Buzzy