Как join () дает разные результаты в зависимости от аргументов? - PullRequest
15 голосов
/ 17 июня 2019

Я не совсем понимаю, почему приведенный ниже вызов join () дает разные результаты в зависимости от типа предоставленных аргументов.

Вот что я нашел:

var test = function() {
  var args = Array.prototype.join.call(arguments,"_");
  return args
};

console.log(test([1,2,3])) // #1: returns 1,2,3
console.log(test(1,2,3)) // #2: returns 1_2_3

Учитывая соединение (аргументы, '_'), не должно ли оно создать строку с разделителями _ в обоих тестах выше?Почему # 1 возвращает значение, разделенное запятыми?

Ответы [ 6 ]

12 голосов
/ 17 июня 2019

Когда вы передаете массив в test, объект arguments становится массивом массивов , а не простым массивом простых значений.Это разница между

arguments = [[1,2,3]];

и

arguments = [1,2,3];

Когда вы вызываете .join для массива массивов, каждый внутренний массив сначала неявно приводится к строке, в результате чего '1,2,3' - значения внутренних массивов не получают .join, редактируемые разделителем, только непосредственные дочерние элементы внешнего массива получают .join, редактируемые разделителем.

5 голосов
/ 17 июня 2019

В вашем коде у вас есть только один аргумент в первом примере, который является массивом.Присоединение к одному элементу удалит скобки:

var test = function() {
  var args = Array.prototype.join.call(arguments,"_");
  return args
};

console.log(test([1,2,3])) // args = [[1,2,3]]
console.log(test(1,2,3)) // args = [1,2,3]

console.log([[1,2,3]].join('_'))
console.log([1,2,3].join('_'))

Еще один способ взглянуть на это - предоставить другой массив в качестве аргумента для test():

var test = function() {
  var args = Array.prototype.join.call(arguments,"_");
  return args
};

console.log(test([1,2,3], [4,5,6]))
4 голосов
/ 17 июня 2019

В первом примере вы не вызываете .join для массива , а для arguments. Эта переменная будет заполнена массивоподобным объектом, у которого массив является первым индексом, по сути, вы вызываете эквивалент:

let myArguments = [[1, 2, 3]];

console.log(myArguments.join("_"));

вместо того, что вы делаете (эквивалент) во втором примере:

let myArguments = [1, 2, 3];

console.log(myArguments.join("_"));
3 голосов
/ 17 июня 2019

Результат отличается, потому что arguments отличается.

При первом вызове (test([1,2,3]) у вас есть один аргумент, который является массивом. Во втором вызове у вас есть 3 аргумента, каждыйодин - число.

Array.prototype.join предназначен для вызова через массивы. Он будет приводить к строковому упорядочению каждого из элементов в массиве.

В вашем первом случае аргументы "массив"имеет только один член, который является самим массивом. Этот аргумент будет строковым. Массив строковых данных станет именно тем, что зарегистрировано в вашем коде.

3 голосов
/ 17 июня 2019

Поскольку вы передаете один аргумент, который является массивом - поэтому он преобразует его в строку, а затем пытается присоединить его к другим аргументам (их нет), поэтому он просто возвращает строку.

var test = function() {
  var args = Array.prototype.join.call(arguments, "_");
  return args
};

console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));

Вы можете решить эту проблему, проверив, передан ли только один аргумент.

var test = function() {
  var args = arguments.length == 1 ? arguments[0].join("_") : Array.prototype.join.call(arguments, "_");
  return args;
};

console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));
3 голосов
/ 17 июня 2019

Первый, первый аргумент - [1,2,3], который соединяется со вторым аргументом, который является ничем -> вывод - [1,2,3].toString().

Второй вызов, на самом деле он объединяет все 3 аргумента, что приводит к выводу 1_2_3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...