String(value)vs value.toString()有什么区别


104

JavaScript在类型和类型转换方面有很多“技巧”,所以我想知道这两种方法是否相同,或者是否存在使它们不同的特殊情况?

Answers:


121

它们并不完全相同,实际上,作为函数调用的String构造函数(您的第一个示例)将在最后调用toString传递的对象的方法,例如:

var o = { toString: function () { return "foo"; } };
String(o); // "foo"

另一方面,如果标识符引用nullundefined,则不能使用该toString方法,它将为您提供TypeError异常

var value = null;
String(null);     // "null"
value.toString(); // TypeError

String称为函数的构造函数大致等同于:

value + '';

对象基本类型的类型转换规则在规范([[DefaultValue]]内部操作)中进行了详细说明。

概括地说,从转换时目标 -到- 字符串,采取以下步骤:

  1. 如果可用,请执行该toString方法。
    • 如果result原始值,则返回result,否则转到步骤2。
  2. 如果可用,请执行该valueOf方法。
    • 如果result原始值,则返回result,否则转到步骤3。
  3. 投掷TypeError

根据上述规则,我们可以举一个涉及的语义的例子:

var o = {
  toString: function () { return "foo"; },
  valueOf:  function () { return "bar"; }
};

String(o); // "foo"

// Make the toString method unavailable:
o.toString = null;

String(o); // "bar"

// Also make the valueOf method unavailable:
o.valueOf = null;

try { 
  String(o); 
} catch (e) {
  alert(e); // TypeError
}

如果您想进一步了解此机制,建议您查看ToPrimitiveToString内部操作。

我还建议阅读本文:


1
如果您调用此方法,则存在第三个“方式”:new String(value)在任何值上,它将始终返回字符串对象。
Herbertusz '16

@Herbertusz new String({toString: null})抛出一个TypeError
КонстантинВан”,19年

与添加的符号String()+ ''现在有相当大的区别。String(Symbol())会运行,但Symbol() + ''会引发错误(并且Symbol()将传递一个false防护,与null和undefined不同,因此x && (x + '')现在可以抛出)。
yeerk '19

24

value.toString()如果value为null 将导致错误。String(value)不应该。

例如:

var value = null;
alert(value.toString());

会因为失败value == null

var value = null;
alert(String(value));

应该显示一条显示为“ null”(或类似)的消息,但不会崩溃。


3
我从未在javascript中看到空指针异常...在哪里看到的?
Dagg Nabbit 2010年

很好 它会用一个例子可以更好尚
mykhal

@否,@ casablanca已修复。我已经习惯了Java。@mykhal看起来如何?
乔纳森

它返回字符串“ null” :)
moefinley

1

String(value)应该具有与value.toString()每种情况相同的结果,除了没有诸如null或的属性的值undefined''+value将产生相同的结果。


1

String() [ 构造函数调用 ]基本上是在调用.toString()

.toString()String()可以在原始值(数字,布尔值,字符串)上调用,并且基本上不会做任何特别的事情:

true =>'true'

假=>'假'

17 =>'17'

'hello'=>'hello'

但是,在对象上调用这些函数会使事情变得有趣:

如果对象具有它自己的.toString()函数,则在您需要将此对象视为字符串时(显式/隐式)将调用它

let obj = {
           myName:"some object",
           toString:function(){ return this.myName; } 
          }

//implicitly treating this obj as a string
"hello " + obj; //"hello some object"

//OR (explicitly)
"hello " + String(obj) //calling the existent toString function

//OR
"hello " + obj.toString(); //calling toString directly

顺便说一句,如果您想将此对象视为数字,则应在其中定义一个.valueOf()函数。

如果我们都在一个对象中怎么办?

如果我们想将此对象视为字符串=>使用.toString()

如果我们想将此对象视为数字=>使用.valueOf()

如果仅定义.valueOf()怎么办?

无论我们要将对象作为字符串还是数字来处理,都将调用在对象内部定义的.valueOf()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.