Javascript将数组连接到字符串

时间:2013-09-27 00:25:04

标签: javascript arrays string d3.js

我正在使用D3.js,并经常发现自己在transform元素上动态构建d属性(或path属性)。这两者通常需要多个以逗号分隔的数字。

有时我通过将数组连接到字符串来构建我的字符串:

var x = 0,
y = 1,
path = 'M0,0 L' + [x, y];

有时我通过手动添加逗号来构建我的字符串:

var x = 0,
y = 1,
path = 'M0,0 L' + x + ',' + y;

我已经决定我应该尝试坚持一种方法或另一种方法,并且我想知道哪种方法更好。

以下是我考虑过的一些事情:

  • 我知道调用join()比手动连接逗号要慢,但这是浏览器在将数组连接到字符串时的作用吗?
  • 第二种格式适用于任何浏览器。是否有任何浏览器不支持第一种格式?
  • 第一种格式使用较少的字符(保持较低的文件大小始终是一个加号)。
  • 就个人而言,我认为第一种格式更具可读性。

有没有一种方式明显优于另一种方式?或者我只是在挑剔?

2 个答案:

答案 0 :(得分:11)

当JavaScript将数组强制转换为字符串时,它实际上会在数组上调用.join(',')。因此,您实际上将使用.join(',')手动获得更好的性能,而不是将其留给解释器以注意您正在强制执行数组。所以:x + ',' + y是最快的,[x, y].join(',')是最佳做法(因为它可以更容易地修改行为),[x, y]比手动调用.join慢一点。并且有时可能无法阅读,但它更方便。

答案 1 :(得分:5)

简短回答:使用array.join。

答案很长:

首先,连接并不比使用array.join()更快,它更慢。这是因为每次连接时都会销毁两个字符串并创建一个新字符串。

采取以下代码:

<script>
function concat(){
var txt = '';
for (var i = 0; i < 1000000; i++){
txt =+ i + ',';
}
}

function arr(ar){
var txt = 'asdf' + ar;
}

ar = [];
for (var i = 0; i < 1000000; i++) {
ar.push(i);
}

concat();

arr(ar);

alert('done!');
</script>

并将其粘贴到html文件中。然后对其进行分析在我的机器上(核心i7EE,16GB RAM,SSD磁盘,IE9),arr()需要0ms而concat()需要12ms。请记住,这是超过一百万次迭代(在IE6上,相同的测试会有很大不同,concat()需要几秒钟。)

其次,当只有两个值时,连接将与array.join相同。所以对于你的例子,从性能的角度来看,它们都是等价的。如果您使用上面的代码并将1000000更改为4,则concat和arr都需要0ms才能执行。这意味着您的特定流量的差异要么不存在,要么可以忽略不计,不会显示在配置文件中。

第三,现代浏览器无论如何都使用array.join()来优化字符串连接,所以从性能的角度来看,讨论可能没有实际意义。

这让我们有了风格。就个人而言,我不会使用第一种形式,因为我不喜欢手动连接字符串(当你有2个变量时,它相当简单,但是如果你有10个变量呢?那将会产生很长的代码。如果你收到一个带有n个值的数组,那么会出现一个for循环)。我不会使用第二种形式,因为正如在另一个答案中指出的那样,值被强制转换为字符串,这意味着正在进行一些隐式转换。这里的问题是隐含的部分。我知道现在阵列在强制时用逗号连接,但是如果规范发生变化,或者某些天才决定在代码库中更改Array.prototype的toString实现会发生什么?只是为了好玩,在jsfiddle中运行:

Array.prototype.toString = function() {
return 'not the expected result!';
}

alert([1, 2]);

你能猜出答案是什么吗? (上面的代码将为您的代码执行与数组相同的转换。通过toString()方法强制执行)

如果你使用array.join(',');通过声明:1)无论toString实现如何,您的数组都将被连接,并且2)它将以逗号连接。