字符串对象和原始字符串之间的区别

时间:2013-06-27 22:01:51

标签: javascript

我的问题在下面通过示例进行了描述 数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有什么区别?为什么输出不同?

3 个答案:

答案 0 :(得分:13)

本声明:

var myString = new String('foo');

...创建一个字符串对象,使用字符foo进行初始化。

本声明:

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。