配列の要素を別の配列に追加したかったので、これを試しました:
[1,2] + [3,4]
それは次のように応答しました:
"1,23,4"
何が起こっている?
[5,6,7][1,2]
は7
2番目の配列の最後の項目を使用するためです。Oo
配列の要素を別の配列に追加したかったので、これを試しました:
[1,2] + [3,4]
それは次のように応答しました:
"1,23,4"
何が起こっている?
[5,6,7][1,2]
は7
2番目の配列の最後の項目を使用するためです。Oo
回答:
+
オペレータは、アレイ用に定義されていません。
何が起こるかというと、Javascriptは配列を文字列に変換し、それらを連結します。
この質問とその結果の私の答えは非常に注目を集めているので、私はオペレーターが一般的にどのように振る舞うのかについての概要を知ることは有用で適切だと感じました+
。
だから、ここに行きます。
E4Xおよび実装固有のものを除いて、JavaScript(ES5現在)には6つの組み込みデータ型があります。
注意がいることをtypeof
、やや紛らわしい返し object
ヌルのためにとfunction
呼び出し可能オブジェクトのために、ヌルが実際にオブジェクトと厳密ではありません、仕様準拠のJavaScript実装ですべての機能がオブジェクトであると考えられています。
そうです-Javascriptにはそのようなプリミティブ配列はありません。ObjectのインスタンスのみがArray
、痛みを和らげるためにいくつかの構文糖で呼び出されました。
混乱にさらに追加するとnew Number(5)
、new Boolean(true)
やなどのラッパーエンティティnew String("abc")
はすべて、object
数値、ブール値、または文字列ではなく、すべて型です。それにも関わらず、算術演算子のためNumber
とBoolean
数字として振る舞います。
簡単でしょ?以上がすべて終了したので、概要に移ります。
+
オペランドタイプ別の異なる結果タイプ
|| undefined | null | boolean | number | string | object |
=========================================================================
undefined || number | number | number | number | string | string |
null || number | number | number | number | string | string |
boolean || number | number | number | number | string | string |
number || number | number | number | number | string | string |
string || string | string | string | string | string | string |
object || string | string | string | string | string | string |
* Chrome13、FF6、Opera11、IE9に適用されます。他のブラウザとバージョンを確認することは、読者の練習問題として残しておきます。
注:CMSで指摘されているようにNumber
、などのオブジェクトの特定のケース、Boolean
およびカスタムオブジェクトでは、+
演算子は必ずしも文字列結果を生成しません。オブジェクトからプリミティブへの変換の実装によって異なります。例えばvar o = { valueOf:function () { return 4; } };
評価o + 2;
生成6
、number
評価、o + '2'
生産'42'
、string
。
概要テーブルがどのように生成されたかを確認するには、http://jsfiddle.net/1obxuc7m/にアクセスしてください。
JavaScriptの+
演算子には、2つの数値を追加すること、または2つの文字列を結合するという2つの目的があります。配列には特定の動作がないため、配列に文字列に変換してから結合します。
2つの配列を結合して新しい配列を作成する場合は、.concat
代わりにメソッドを使用します。
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
ある配列から別の配列にすべての要素を効率的に追加したい場合は、.pushメソッドを使用する必要があります。
var data = [1, 2];
// ES6+:
data.push(...[3, 4]);
// or legacy:
Array.prototype.push.apply(data, [3, 4]);
// data is now [1, 2, 3, 4]
+
演算子の動作はECMA-262 5eセクション11.6.1で定義されています。
11.6.1加算演算子(+)
加算演算子は、文字列連結または数値加算を実行します。生産
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
は次のように評価されます。
lref
を評価した結果としましょうAdditiveExpression
。- してみましょう
lval
ことGetValue(lref)
。rref
を評価した結果としましょうMultiplicativeExpression
。- してみましょう
rval
ことGetValue(rref)
。- してみましょう
lprim
ことToPrimitive(lval)
。- してみましょう
rprim
ことToPrimitive(rval)
。- で
Type(lprim)
あるString
かでType(rprim)
あるString
場合、
- 連結した結果である文字列を返します
ToString(lprim)
が続くとToString(rprim)
ToNumber(lprim)
とに加算演算を適用した結果を返しToNumber(rprim)
ます。下記の11.6.3の注を参照してください。
各オペランドが変換されていることがわかりToPrimitive
ます。さらに読むToPrimitive
と、配列が常に文字列に変換され、この結果が生成されることがわかります。
Array.prototype.push.apply(data, [3, 4])
代わりに、より詳細なものを使用するのはなぜdata.concat([3,4])
ですか?
concat
作成します。呼び出しが長いほど、既存の配列を効率的に拡張します。
[].push.apply(data, [3,4])
少し冗長に使用できます。また、それはの値を変更する他の人々に耐性があることが保証されていますArray
。
[1,2]+[3,4]
JavaScriptでの評価と同じです:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
したがって、問題を解決するには、2つの配列を同じ場所に追加するか、新しい配列を作成しないでください。
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
それはまさにあなたがそれをするように頼んだことをしています。
一緒に追加しているのは、配列参照(JSが文字列に変換する)であり、見かけ上の数値ではありません。これは文字列を一緒に追加するようなものです:"hello " + "world"
="hello world"
JavaScriptでオペレーターをオーバーロードできてもできなかった場合は、すばらしいでしょう 。JavaScriptでカスタムオペレーターオーバーロードを定義できますか? 比較する前に文字列に変換する「==」演算子のみハッキングできます:http : //blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
+演算子は、オペランドが数値でない場合、オペランドが文字列であると想定するためです。したがって、最初にそれらを文字列に変換し、連結していない場合は、最終的な結果を返します。また、配列はサポートしていません。
ここでは、予期しない望ましくない出力('1,23,4'
)がどのように発生するかを説明する回答と、期待される望ましい出力([1,2,3,4]
)であると想定されるもの、つまり配列連結を取得する方法を説明する回答があります。ただし、元の質問は単に「配列の要素を別の要素に追加したかった」と述べているため、期待される望ましい出力の性質は実際にはややあいまいです。すなわち、可能性配列の連結を意味するが、それは可能性も平均タプル添加(例えば、ここでおよびここで)、すなわち組み合わせ例えば、第二の対応する要素のスカラー値、1つの配列内の要素のスカラー値を加算[1,2]
し、[3,4]
得ること[4,6]
。
両方の配列のアリティ/長さが同じであると仮定すると、次の1つの簡単な解決策があります。
const arr1 = [1, 2];
const arr2 = [3, 4];
const add = (a1, a2) => a1.map((e, i) => e + a2[i]);
console.log(add(arr1, arr2)); // ==> [4, 6]