2012-04-28 54 views
19

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

为什么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". 
...   | ... 
*/ 

回答

22

在审查我以前的答案后,似乎对我以前的答案的全面检修是必要的。由于简单的答案是这些是标准特定的特殊情况,所以我把它复杂化了。

specificationString()String用作函数):

15.5.1.1字符串([值])

返回的ToString计算的字符串值(不是一个字符串对象)(值)。如果值不是>提供的,则返回空的 字符串“”。

ToString功能(即在内部存在,而不是在用户级)被定义如下(9.8):

“的抽象操作的ToString它的参数,根据表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 2012-04-28 09:52:31

+0

@Kooilnc没问题。 – Corbin 2012-04-28 09:58:05

+0

String()!== String(未定义)是因为在JavaScript中,只有两个对象在内存中是相同的对象时它们才相等。当调用String()时,你正在字符串基元周围创建一个包装器对象,所以基本上这个比较是两个不同的对象包装相同的字符串基元。 – Buzzy 2014-05-12 07:13:54

2

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

MDN says

它可以使用String作为一个“更安全”的toString的选择,因为尽管它仍然正常调用底层的toString,它也适用于null和undefined。

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(有特殊皈依情况表)传递给值转换它到一个字符串。

+1

与我连接的表格完全相同,除了点上的绿色。 (和一个直接链接) – Corbin 2012-04-28 09:27:02

相关问题