2012-04-28 4 views
19

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

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

[редактировать]: из спецификации 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". 
...   | ... 
*/ 

ответ

22

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

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.

+0

Спасибо за ваш ответ Корбин, это ясно. – KooiInc

+0

@Kooilnc Нет проблем. – Corbin

+0

String()! == String (undefined) - это потому, что в JavaScript два объекта равны, только если они являются одним и тем же объектом в памяти. При вызове String() вы создаете объект-оболочку вокруг примитива строки, поэтому по существу сравнение состоит из двух разных объектов, обертывающих один и тот же примитив строки. – Buzzy

2

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

MDN says:

Можно использовать строки в качестве «безопасного» ToString альтернативы, как, хотя он по-прежнему обычно называет основной ToString, он также работает на нуль и неопределенными.

0

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

1

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

+1

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

Смежные вопросы