Вопрос по javascript, string – Почему String (null) работает?

21

null а такжеundefined не имеютtoString или жеvalueOf метод. Афаик с помощьюString вызываетtoString метод его параметра (например,String({}) = & GT;[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".
...            | ...
*/

Ваш Ответ

4   ответа
28

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

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

15.5.1.1 String ( [ value ] )

Returns a String value (not a String object) computed by ToString(value). If value is not supplied, the empty String "" is returned.

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

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

Argument Type | Result
Null | "null"
Undefined | "undefined"

Это означает, чтоString(null) а такжеString(undefined) зайдите в эту специальную таблицу типов и просто верните значения строки"null" а также"undefined".

Псевдо-реализация user-land выглядит примерно так:

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 действительно есть особый случай.

делает эту работу, что странно:x={null:1}; x["null"];//1 x[null]; //1
@ Buzzy Я рад, что вы прокомментировали. Перечитав мой старый ответ, я понял, что это слишком сложно, что является очень четкой функциональностью в спецификации! :)
@Kooilnc Нет проблем.
Спасибо за ваш ответ, Корбин, все ясно. KooiInc
String ()! == String (undefined) объясняется тем, что в JavaScript два объекта равны, только если они являются одним и тем же объектом в памяти. При вызове String () вы создаете объект-оболочку вокруг строкового примитива, поэтому по существу сравнение состоит из двух разных объектов, обертывающих один и тот же строковый примитив.
0

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

2

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

MDN говорит:

It's possible to use String as a "safer" toString alternative, as although it still normally calls the underlying toString, it also works for null and undefined.

1

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

Это та же самая таблица, на которую я ссылался, за исключением зеленого цвета в пятнах. (И прямая ссылка)

Похожие вопросы