Я хотів додати елементи масиву в інший, тому спробував це:
[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, A number, оцінка o + '2'виробляє '42', A 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]
Поведінка +оператора визначена у розділі 11.6.1 ECMA-262 5e :
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]
Іншим результатом із використанням простого знака "+" буде:
[1,2]+','+[3,4] === [1,2,3,4]
Отже, щось подібне повинно працювати (але!):
var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]
... але вона перетворить змінну змінної з масиву в рядок! Майте це на увазі.