由于JavaScript中的字符串是基本类型,将字符串传递给函数会创建它的本地副本吗?我对此感到疑惑,因为在字符串被创建后就不能修改,所以看起来JavaScript虚拟机不会仅仅在内部传递字符串的地址。
如果有人告诉我不必担心这个问题(与Web开发人员交谈时经常发生这种情况),那么我正在开发HTML5游戏,垃圾收集是一个主要问题,所以我真的需要知道。
由于JavaScript中的字符串是基本类型,将字符串传递给函数会创建它的本地副本吗?我对此感到疑惑,因为在字符串被创建后就不能修改,所以看起来JavaScript虚拟机不会仅仅在内部传递字符串的地址。
如果有人告诉我不必担心这个问题(与Web开发人员交谈时经常发生这种情况),那么我正在开发HTML5游戏,垃圾收集是一个主要问题,所以我真的需要知道。
这个字符串将会被按引用传递。
字符串是不可变的,所以无论何时你尝试改变它,都会得到一个新的字符串(例如通过 value+="more"
进行操作)。
另外请参见:什么是不可变的?
@T.J. Crowder: 按值传递与按引用传递 - 如果你正在看语言定义,那么你是正确的。然而,我认为没有一种实现会真正创建字符串的副本,因为这样做会非常慢。此外,由于字符串是不可变的原始类型,所以没有必要复制它们,因为它们不能被改变。
我认为规范对这一点是没有明确说明的。但是,如果传递实际字符串内容而不是传递指向内存中该内容的引用,那么这将是一个真正愚蠢的实现,即使字符串在理论上是“原语”。我怀疑大多数实现在处理“原语”字符串时与处理对象引用的方式相似(在这方面,显然不同于其他方面,例如 ===
),但只是没有使用 Object
类的附属物。
b
有一个 bar
属性会更合理吧?var a = "foo"
var b = a;
a["bar"] = "baz";
console.log(b["bar"]);
现在,我确定有些地方出了问题,导致我感到困惑,这是什么原因呢? - doubleOrta
[包含/具有对] 原始值字符串 "foo"
的引用。语句 a["bar"] = "baz"
从 a
获取原始字符串,但由于它随后将其用作对象,因此会创建一个新的临时字符串对象并用于表达式的该部分。该临时字符串对象获得了 bar
属性,但由于没有保存... (续) - T.J. Crowdera
的值设置为一个对象,然后将其值设置为 null
,那么该对象就会被垃圾回收。这是因为当我们将 a
的值设置为 null
时,它不再引用该对象。只要没有任何地方引用该对象(不是 a
,当然也不是 b
),该对象就立即可以进行垃圾回收。同时,a
(和 b
)仍然包含或引用原始字符串 "foo"
,由于是原始类型,因此无法具有临时属性。这种行为在规范中的PutValue操作中有所描述。我们可以通过向 String.prototype
添加一个方法来观察字符串对象的创建...(续) - T.J. CrowderObject.defineProperty(String.prototype, "getObject", {value: function() { return this; });
(http://jsfiddle.net/tyfozkmp/) 请注意,这是在松散模式下(非严格模式)。如果它在严格模式下,即使字符串对象会被创建(至少在规范术语中),我们也不会将其视为 this
,因为原始值(原始类型)会作为 this
传递而不是字符串对象(在严格模式下,this
可以是原始类型;但在松散模式下不行)。这对于多种原因都很方便,尤其是为了启用 JavaScript 引擎的优化。有趣吧? :-) - T.J. Crowdera["bar"]
返回 undefined
,我还以为它会返回 "baz"
!感谢解释,很抱歉回复晚了。首先允许这种行为是否更合适(通过在尝试向字符串添加属性时抛出错误),这样的表达式是不是毫无用处? - doubleOrt
delete
语句来释放新创建的对象。 - user2193789delete
与垃圾回收完全无关。这不是C++,JavaScript中的delete
意味着完全不同的东西。 - T.J. Crowder