2017-09-13 29 views
4

鉴于以下代码的新的数组:在阵列中按字符串元素的参考串

var old_Array =["One","Two","..."]; 
    var len = old_Array .length; 
    var new_Array =[]; 
    for(var i=0;i<len;++i) 
    { 
     new_Array.push(old_Array [i]); // ----- [1] 
    } 

线后[1]new_Array填充有字符串。

  1. 是每个元素实际上是在 old_Array,字符串元素引用或复制每个字符串元素?
  2. 是否JavaScript解释器/编译器优化线 - [1]通过 在old_Array每个字符串元素的推引用?
+5

只有通过引用传递对象,才会复制类似字符串的基元。 –

+0

@PatrickEvans感谢您的快速答复。但JavaScript引擎优化该代码行吗?因为该字符串对象的内存分配已经存在于old_Array中了......我们是否可以传达编译器,我们需要在那里进行优化......而不是每个元素的深度复制或浅拷贝 – Buddhika

+0

想想old_Array是否有大量的字符串元素。许多复制操作将会发生。 – Buddhika

回答

1

对第一个问题的回答:每个元素只是旧数组的每个字符串元素的副本。 如果数组包含对象引用,则将引用复制到新数组中。 (在这种情况下,像字符串和数字这样的基本类型被按值复制。)

对第二个问题的回答:不,JavaScript解释器不会通过推送old_Array中每个字符串元素的引用来优化行[1] 。

更快和更好的方法来复制的阵列是:

var new_Array = old_Array.slice(); 

它克隆旧数组,并返回参照新的数组。

+1

谢谢.yeah slice()与克隆的概念一起工作。当你考虑每个两个数组的基数时,认为你想在new_Array内部有old_array元素的一部分,为了表示的目的,我们可以有new_Array结构,如果我们有100000旧数组中的字符串元素,当我们必须使用5000个而不是克隆时,我们创建新的数组结构,其中5000个数据已经存在于旧数组中,因此,而不是5000次复制操作,我们可以直接指定数据的内存位置,已通过引用存在于旧数组中。 – Buddhika

+0

@Buddhika在这种情况下,你必须确保旧的数组不会被删除。另外,如果元素大小较小,将元素复制到新数组将更有意义。如果数组元素的大小过大,则通过引用访问它们将是最佳选择。 –

1

有趣的问题。事情是字符串是不可变的,这意味着一旦它们写在内存中,它们不能被改变。所以,当你不喜欢

var s2 = s.substr(0, 3); 

s2现在是一个新的字符串,但它不会复制到新的存储位置,而不是代表就像s一个范围。因此,根据你的问题,从一个字符串数组复制一个字符串不应该为新字符串分配额外的内存。但是,当原始字符串的数组不再需要时,GC应该足够聪明,以确定要从该数组分配的内存中删除哪些项目。

我猜这些实现会根据JS引擎而改变。这里有关于此主题的MDN的一些信息。

+0

感谢您的关注和答复。 – Buddhika

+0

顺便说一下,只要s2不会被改变,它可以表示为s的范围,但是如果我们假设javascript解释器/编译器有深入的代码分析和运行时检查,它可以优化s2,就像range用新的内存分配来代替新的String的表示,但是如果它检测到对s2的任何修改,它会分配新的内存吗? – Buddhika

+0

@Buddhika's2'会发生什么样的变化..?记住's2'也是不可变的。唯一可能发生的情况是在没有更多代码被引用时被垃圾收集器(GC)删除。 – Redu