Подтвердить что ты не робот

Почему работает String (null)?

null и undefined не имеют метода toString или valueOf. Afaik с помощью String вызывает метод toString своего параметра (например, String({}) = > [object Object]).

Почему работают String(null) или String(undefined? Это не подразумевает Object.prototype.toString.call(null). потому что это оценивается как [object Null].

[edit]: из спецификации ECMA-262/5th edition (стр. 48). Это не добавляет разъяснений, я бы сказал:

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

Ответ 1

После рассмотрения моего предыдущего ответа, кажется, необходим полный пересмотр моего предыдущего ответа. Я немного усложнил это, так как короткий ответ заключается в том, что это особые случаи, отмеченные стандартами.

спецификация для String() (String используется как функция):

15.5.1.1 Строка ([значение])

Возвращает значение String (не объект String), вычисленное ToString (значение). Если значение не указано > , пустое Возвращается строка "".

Функция ToString (которая существует внутренне, а не в userland) определяется следующим образом (9.8):

"Абстрактная операция ToString преобразует свой аргумент в значение типа String в соответствии с таблицей 13"

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));
}

НеStringStringString (что, по сути, представляет интерес), удачно определяется в psuedo-JS-land. Как вы можете видеть, действительно существует специальный случай для null/true/false/ undefined.

Ответ 2

Вероятно, есть несколько дополнительных проверок и обработки для особых случаев, таких как null и undefined.

MDN говорит:

Можно использовать String как "безопасную" альтернативу toString, хотя, хотя она по-прежнему обычно вызывает базовую функцию toString, она также работает для null и undefined.

Ответ 3

Вам может быть интересно увидеть Annotated ES5 (это гораздо более читаемо, чем PDF файл ECMAScript 5), в котором говорится: new String([ value ]) http://es5.github.com/#x15.5.2.1 вызывает [ToString] http://es5.github.com/#x9.8 (там представляет собой таблицу особых случаев конвертации), чтобы преобразовать переданное ему значение в строку.

Ответ 4

String(null) создает строковый объект и передает ему значение по умолчанию null.