Answers:
它们并不完全相同,实际上,作为函数调用的String构造函数(您的第一个示例)将在最后调用toString传递的对象的方法,例如:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
另一方面,如果标识符引用null或undefined,则不能使用该toString方法,它将为您提供TypeError异常:
var value = null;
String(null); // "null"
value.toString(); // TypeError
String称为函数的构造函数大致等同于:
value + '';
从对象到基本类型的类型转换规则在规范([[DefaultValue]]内部操作)中进行了详细说明。
概括地说,从转换时目标 -到- 字符串,采取以下步骤:
toString方法。
result是原始值,则返回result,否则转到步骤2。valueOf方法。
result是原始值,则返回result,否则转到步骤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
}
如果您想进一步了解此机制,建议您查看ToPrimitive和ToString内部操作。
我还建议阅读本文:
new String({toString: null})抛出一个TypeError。
String()和+ ''现在有相当大的区别。String(Symbol())会运行,但Symbol() + ''会引发错误(并且Symbol()将传递一个false防护,与null和undefined不同,因此x && (x + '')现在可以抛出)。
value.toString()如果value为null 将导致错误。String(value)不应该。
例如:
var value = null;
alert(value.toString());
会因为失败value == null。
var value = null;
alert(String(value));
应该显示一条显示为“ null”(或类似)的消息,但不会崩溃。
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()
new String(value)在任何值上,它将始终返回字符串对象。