27

null并且undefined没有toStringorvalueOf方法。Afaik usingString调用toString其参数的方法(例如String({})=> [object Object])。

那为什么要做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".
...            | ...
*/
4

4 回答 4

36

在查看了我之前的答案之后,似乎有必要对我之前的答案进行彻底检查。我把它复杂化了,因为简短的回答是这些是标准指定的特殊情况。

(用作函数)的规范:String()String

15.5.1.1 字符串([值])

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

ToString函数(存在于内部,不在用户空间中)定义如下(9.8):

“根据表 13,抽象操作 ToString 将其参数转换为 String 类型的值”

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

这意味着进入这个特殊的类型表String(null)String(undefined)只返回字符串值 value"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))
    }
}

(请注意,此示例忽略了构造函数 case ( 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 的特殊情况。

于 2012-04-28T09:10:06.203 回答
2

对于 和 等特殊情况,可能只有一些额外的检查和null处理undefined

MDN 说

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

于 2012-04-28T09:13:25.887 回答
1

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

于 2012-04-28T09:20:32.750 回答
1

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

于 2012-04-28T09:26:21.323 回答