web-dev-qa-db-ja.com

JavaScriptの+演算子とconcat()メソッドの違いは何ですか

plus(+)演算子およびString.concat()メソッドを使用しても同じ結果が得られます。

plus(+)演算子;

str1 + str2;

String concat()メソッド;

str1.concat(str2);

さらに、それは w3schools で書かれています。

ただし、JavaScriptを使用すると、JavaScriptはメソッドとプロパティを実行するときにプリミティブ値をオブジェクトとして扱うため、プリミティブ値にもメソッドとプロパティを使用できます。

では、JSのプリミティブまたはStringオブジェクトのどちらを使用する場合、どちらを組み合わせる方が良いでしょうか。それらの間にパフォーマンスの利点と欠点がある場合はどうなりますか?

var firstName = "John"      // String
var y = new String("John"); // with String Object

同じ結果が得られるサンプルコードを以下に示します。

function example1 () {
  var str1 = "Hello ";
  var str2 = "World!";
  document.getElementById("demo1").innerHTML += str1 + str2;
}


function example2 () {
  var str1 = "Hello ";
  var str2 = "World!";
  document.getElementById("demo2").innerHTML += str1.concat(str2);
}

function example3 () {
  var str1 = String("Hello ");
  var str2 = String("World!");
  document.getElementById("demo3").innerHTML += str1 + str2;
}

function example4 () {
  var str1 = String("Hello ");
  var str2 = String("World!");
  document.getElementById("demo4").innerHTML += str1.concat(str2);
}

example1();
example2();
example3();
example4();
<p id="demo1">Demo 1: </p>
<p id="demo2">Demo 2: </p>
<p id="demo3">Demo 3: </p>
<p id="demo4">Demo 4: </p>
17

かなり同じですが+はより明確で、確かに高速です。

this performance test を見て、- this も参照してください

Concat()メソッドの代わりに代入演算子(+、+ =)を使用することを強くお勧めします。

6
Robert

プリミティブの文字列メソッドとオブジェクトの文字列メソッドの動作に違いはありません。

プリミティブバージョンは this jsperf (おそらく100倍も高速)ではるかに高速に見えるため、パフォーマンスに大きな違いがあります。これはおそらくインタープリターの最適化が原因です。

enter image description here

this jsperf からわかるように、パフォーマンスの主な違いは_var str1 = "Hello ";_ではなくvar str1 = new String("Hello ");が原因です。 _+_演算子とconcat()演算子の違いはほとんどありません。私の推測では、これはJSインタプリタが文字列メソッドを最適化しているためです。ただし、実際の文字列オブジェクトを作成することは、最適化も効率化もされていません。

ECMAScript仕様については、 _+_ のECMAScript仕様では、左のオペランド(lprim)のプリミティブ値が文字列の場合、その文字列を返すことを明示的に示しています。 ToString(lprim) followed by ToString(rprim)を連結した結果。

String.prototype.concat()のECMAScript仕様 には、Let R be the String value consisting of the characters in the previous value of R followed by the characters of ToString(next).と記載されています。

この表現は、文字列として左のオペランドが指定された場合、_+_が右のオペランドを文字列にキャストし、.concat()とまったく同じように.concat()を内部的に呼び出すことを意味します。

明らかに、左側のオペランドが文字列ではない場合、_+_を使用すると、必ずしも文字列操作として扱われるとは限らないため、別の動作になります。


文字列オブジェクトと文字列プリミティブのどちらを使用しても違いが生じる可能性があるのは、カスタムプロパティを文字列オブジェクトに追加する場合に、プリミティブフォームではなくオブジェクトフォームが必要な場合です。

_+_をいつ使用するか、および.concat()をいつ使用するかについては、これは個人的なコーディングスタイルの選択です。どちらも同じ結果になります。個人的には、コードを読みやすくするため、可能な限り演算子を使用することを好みます。

文字列オブジェクトを作成する特別な理由がない限り、通常はプリミティブのみを使用する必要があります。

したがって、これを行う理由は本当にありません。

_var str1 = String("Hello ");
var str2 = String("World!");
document.getElementById("demo").innerHTML = str1.concat(str2);
_

これがうまくいくとき:

_var str1 = "Hello ";
var str2 = "World!";
document.getElementById("demo").innerHTML = str1 + str2;
_

ここに、明示的な文字列オブジェクトが必要になる/必要になる可能性があるときに知っている唯一の例を示します。

_// actual string object will retain custom property
var str1 = new String("Hello");
str1.customProp = "foo";
log(str1.customProp);

// string primitive will not retain custom property
var str2 = "Hello";
str2.customProp = "foo";
log(str2.customProp);

function log(x) {
    document.write(x + "<br>");
}_
13
jfriend00

機能による違いはありませんが、「+」演算子の方がconcat()より高速です。

var str1="hello";
var str2="world";
var str3;
var start = new Date().getTime();
for (i = 0; i < 100000; ++i) {
str3=str1+str2;
}
var end = new Date().getTime();
var time = end - start;

print('Execution time using + operator: ' + time);

// USING CONCAT OPERATOR

start = new Date().getTime();
for (i = 0; i < 100000; ++i) {
str3=str1.concat(str2);
}
end = new Date().getTime();
time = end - start;
print('Execution time using CONCAT operator: ' + time);

ideoneで実行してください

1
Ambika