我的问题在下面通过示例进行了描述 数1:
var myString = new String('foo');
如果我使用console.log(myString);
输出为String { 0="f", 1="o", 2="o"}
和数字2:
var myString = new String();
myString = "foo";
此处console.log(mystring);
仅打印foo
这里number-1和number-2有什么区别?为什么输出不同?
答案 0 :(得分:13)
本声明:
var myString = new String('foo');
...创建一个字符串对象,使用字符f
,o
和o
进行初始化。
本声明:
var myString = new String();
...创建一个没有字符的字符串对象,但这并不重要,因为这句话:
myString = "foo";
...将该字符串对象抛出,并将该变量的值替换为带有这些字符的新原语字符串。最终结果与:
完全相同var myString = "foo";
console.log
的输出不同的原因是提供console.log
的浏览器试图明确其中一个是对象而另一个是基元。
有些令人困惑的是,JavaScript既有字符串对象又有字符串基元。 (它还有数字对象和数字基元。)几乎没有任何理由使用new String
来创建一个字符串对象;只需使用原语(在您的情况下,文字)。相反,有很好的理由不使用字符串对象,例如:
console.log(new String("foo") === new String("foo")); // "false"
console.log(new String("foo") == new String("foo")); // "false"
console.log("foo" === "foo"); // "true"
因为字符串对象是对象,==
和===
比较对象引用,而不是字符序列。虽然可能有一些边缘情况,这是你想要的,99.9%的时间,你真正想要的是比较值。好消息是:
console.log("foo" == new String("foo")); // "true"
...但如果您使用===
,则不会出现这种情况,而var myString = "foo"
不执行任何类型强制。
你可能会问:
因此,如果
myString.toUpperCase()
返回一个原语,而不是一个对象,那么{{1}}是如何工作的呢?
好问题:答案是原语会自动提升为一个对象,以便我们可以进行函数调用。 (理论上讲,在实践中,实现比这更聪明。)
答案 1 :(得分:2)
理解的最佳方式是运行这两个语句
console.log(typeof 'foo'); // -> "string"
console.log(typeof new String('foo')); // -> "object"
第二个语句是将myString重新分配给“string”而不是String对象
答案 2 :(得分:2)
console.log(typeof s_prim); // Logs "string"
console.log(typeof s_obj); // Logs "object"
差别很小,特别是因为字符串基元上调用的方法是由字符串对象方法包装的,所以在功能上它们接近相同。
正如MDN reference所指出的,这对eval()调用很重要。如果在字符串对象上调用,Eval将返回对象“2 + 2”,如果在基元上调用则返回4。