Я хотел добавить элементы массива в другой, поэтому я попробовал это:
[1,2] + [3,4]
Он ответил:
"1,23,4"
Что здесь происходит?
[5,6,7][1,2]
, 7
потому что он использует последний элемент во втором массиве. Oo
Я хотел добавить элементы массива в другой, поэтому я попробовал это:
[1,2] + [3,4]
Он ответил:
"1,23,4"
Что здесь происходит?
[5,6,7][1,2]
, 7
потому что он использует последний элемент во втором массиве. Oo
Ответы:
+
Оператор не определен для массивов .
В результате Javascript преобразует массивы в строки и объединяет их.
Поскольку этот вопрос и, следовательно, мой ответ привлекают к себе много внимания, я подумал, что было бы полезно и уместно иметь представление о том, как +
оператор ведет себя в целом.
Итак, вот и все.
За исключением E4X и специфичных для реализации вещей, Javascript (начиная с ES5) имеет 6 встроенных типов данных :
Обратите внимание на то, что хотя это typeof
несколько сбивает с толку возвратов object
для Null и function
для вызываемых объектов, Null на самом деле не является объектом, и, строго говоря, в реализациях Javascript, соответствующих спецификации, все функции считаются объектами.
Это верно - у Javascript нет примитивных массивов как таковых; только экземпляры объекта, вызванные 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 имеет две цели: добавление двух чисел или объединение двух строк. Он не имеет определенного поведения для массивов, поэтому он конвертирует их в строки и затем соединяет их.
Если вы хотите , чтобы объединить два массива , чтобы произвести новый, использовать в .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» . Поэтому, когда +
знак найден, он не может суммировать массивы, а затем объединять их как строки.
В +
concats строки, таким образом он преобразует массивы строк.
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Чтобы объединить массивы, используйте concat
.
[1,2].concat([3,4])
[1,2,3,4]
В JavaScript оператор двоичного сложения ( +
) выполняет как числовое сложение, так и конкатенацию строк. Однако, когда его первый аргумент не является ни числом, ни строкой, он преобразует его в строку (следовательно, " 1,2
"), затем он делает то же самое со вторым " 3,4
" и объединяет их в " 1,23,4
".
Попробуйте вместо этого использовать метод concat для массивов:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Похоже, JavaScript превращает ваши массивы в строки и соединяет их вместе. Если вы хотите добавить кортежи вместе, вам придется использовать цикл или функцию карты.
[1,2]+[3,4]
в JavaScript это то же самое, что и оценка:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
и поэтому, чтобы решить вашу проблему, лучше всего было бы добавить два массива на месте или без создания нового массива:
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,2]
и [3,4]
получение [4,6]
.
Предполагая, что оба массива имеют одинаковую арность / длину, вот одно простое решение:
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]