为什么有两种JavaScriptstring?

这只是刺伤了我。 我不知道是否所有的浏览器(我没有任何其他有能力的浏览器来testing),但至lessFirefox有两种string对象。

打开Firebugs控制台并尝试以下操作:

>>> "a" "a" >>> new String("a") String { 0="a"} 

正如你可以直观看到的,Firefox不同地处理new String("a")"a" 。 不过,不pipe怎样,这两种弦似乎performance相同。 例如,有证据表明两者都使用相同的原型对象:

 >>> String.prototype.log = function() { console.log("Logged string: " + this); } function() >>> "hello world".log() Logged string: hello world >>> new String("hello world").log() Logged string: hello world 

显然,两者是相同的。 也就是说,直到你问的types。

 >>> typeof("a") "string" >>> typeof(new String("a")) "object" 

我们也可以注意到,当this是一个string时,它总是对象forms:

 >>> var identity = function() { return this } >>> identity.call("a") String { 0="a"} >>> identity.call(new String("a")) String { 0="a"} 

再进一步,我们可以看到,非对象string表示forms不支持任何附加属性,但是对象string会:

 >>> var a = "a" >>> var b = new String("b") >>> a.bar = 4 4 >>> b.bar = 4 4 >>> a.bar undefined >>> b.bar 4 

另外,有趣的事实! 您可以使用toString()函数将string对象转换为非对象string:

 >>> new String("foo").toString() "foo" 

从来没有想过可以调用String.toString() ! 无论如何。

所以所有这些实验都要求问题:为什么JavaScript中有两种string?


评论显示,每种原始JavaScripttypes(包括数字和布尔)也是如此。

在Javascript中有两种types的string – 文字string和string对象。 他们的行为有点不同。 两者之间的主要区别是您可以将其他方法和属性添加到String对象。 例如:

 var strObj = new String("object mode"); strObj.string_mode = "object" strObj.get_string_mode = function() { return this.string_mode; } // this converts it from an Object to a primitive string: str = strObj.toString(); 

string文字只是临时转换为String对象来执行任何核心方法。

同样的概念也适用于其他数据types。 这里有更多关于原始数据types和对象 。

编辑

正如在注释中指出的那样,string文字不是原始string,而是一个“字面常量,其types是一个内置的原始string值”,引用这个来源 。

将string值与string对象比较

"a"是一个string值。

"a" === "a"; // true

new String("a")是一个string对象。

new String("a") === new String("a"); // false

有两个string。 "a"只是获得string值“a”,在new String("a")创build一个新的string对象,其内部具有string值“a”

还有一件要记住的重要事情是:

 typeof "my-string" // "string" typeof String('my-string') // 'string' typeof new String("my-string") // "object". 

因此,当testing一个参数或variables是否是一个string时,您至less需要执行以下操作。

 function isString(arg) { if (!arg) { return false; } return typeof arg == "string" || arg.constructor == String; } 

如果你从另一个frame / iframe传入一个String对象,上面的函数仍然会失败。 那是:

 frames[0].myStringVar.constructor != frames[1].myStringVar.constructor 

这是因为构造函数String对于每个窗口上下文都是不同的。 因此,一个万无一失的isString方法将会是

 function isString(obj) { return Object.prototype.toString.call(obj) == "[object String]"; }