为什么String(null)有效?

时间:2012-04-28 09:05:51

标签: javascript string null tostring

nullundefined没有toStringvalueOf方法。使用String的Afaik会调用其参数的toString方法(例如String({}) => [object Object])。

为什么String(null)String(undefined有效?它不隐含地Object.prototype.toString.call(null)。因为评估结果为[object Null]

[edit]:来自ECMA-262 / 5th版本(第48页)。这不会增加澄清,我会说:

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

4 个答案:

答案 0 :(得分:29)

在回顾我之前的回答后,似乎有必要对我之前的回答进行彻底检查。我很容易让它复杂化,因为简短的回答是这些都是标准规定的特殊情况。

String() specificationString用作函数):

  

15.5.1.1字符串([value])

     

返回由ToString(value)计算的String值(不是String对象)。如果未提供值,则为空   返回字符串“”。

ToString函数(内部存在,不在userland中)定义如下(9.8):

“抽象操作ToString根据表13”

将其参数转换为String类型的值
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的特殊情况。

答案 1 :(得分:2)

对于nullundefined等特殊情况,可能只需要进行一些额外的检查和处理。

MDN says

  

可以使用String作为“更安全”的toString替代方法,因为虽然它通常仍然调用底层的toString,但它也适用于null和undefined。

答案 2 :(得分:1)

您可能有兴趣看到Annotated ES5(比ECMAScript 5 PDF更具可读性),其中指出:new String([ value ]) http://es5.github.com/#x15.5.2.1调用[ToString] {{3 (有一个特殊转换情况表)将传递给它的值转换为字符串。

答案 3 :(得分:0)

String(null)创建一个字符串对象并将其传递给默认值null。