Удаление аргумента из аргументов в JavaScript

Я хотел иметь необязательный параметр boolean для вызова функции:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    // do some stuff
  }
  // rest of function
}

Я хочу, чтобы остальная часть функции видела только массив arguments без необязательного параметра boolean. Первое, что я понял, это то, что массив arguments не является массивом! Вроде стандартный Object со свойствами 0, 1, 2 и т.д. Так и не смог сделать:

function test() {
  if (typeof(arguments[0]) === 'boolean') {
    var optionalParameter = arguments.shift();

Я получаю сообщение об ошибке, что shift() не существует. Так есть ли простой способ удалить аргумент из начала объекта arguments?


person at.    schedule 11.11.2013    source источник
comment
Просто предположение: delete arguments[0]?   -  person putvande    schedule 11.11.2013


Ответы (3)


arguments - это не массив, это массив, подобный объекту. Вы можете вызвать функцию массива в arguments, обратившись к Array.prototype, а затем вызвать его, передав argument в качестве контекста выполнения, используя .apply()

Пытаться

var optionalParameter = Array.prototype.shift.apply(arguments);

Демо

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = Array.prototype.shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

другая версия, которую я видел в некоторых местах,

var optionalParameter = [].shift.apply(arguments);

Демо

function test() {
    var optionalParameter;
    if (typeof (arguments[0]) === 'boolean') {
        optionalParameter = [].shift.apply(arguments);
    }
    console.log(optionalParameter, arguments)
}
test(1, 2, 3);
test(false, 1, 2, 3);

person Arun P Johny    schedule 11.11.2013
comment
Обратите внимание, что это также повлияет на любые именованные аргументы и особенно интересно повлияет на последний предоставленный аргумент, когда к нему обращаются как к именованному аргументу. Если у вас есть function foo(a, b, c), и вы вызываете foo(1, 2, 3) и выполняете описанный выше сдвиг, и b, и c в конечном итоге будут 3. Это может быть то, что вы хотите. Или не. - person T.J. Crowder; 11.11.2013
comment
Удивлен, что это работает! так что shift не только возвращает первый элемент, но и преобразует Object, переданный в array, а затем обратно в Object с удаленным первым элементом? Именно то, что я искал, но удивительно... - person at.; 11.11.2013
comment
@ на самом деле это не то, что он делает. Код сдвига запускается и делает вид, что объект на самом деле является массивом; он не выполняет преобразования. Именно по этой причине этот трюк имеет эффект, отмеченный мистером Краудером. Если вам нужно сделать что-то подобное, вам, вероятно, следует просто преобразовать arguments в массив и работать оттуда. - person Pointy; 11.11.2013
comment
Если вы хотите оставить arguments нетронутым и создать новый массив, используйте слайс: var newArguments = [].slice.call(arguments, 1); - person Christiaan Westerbeek; 23.06.2015
comment
Важно понимать, что в Javascript функции сами по себе являются объектами и поэтому могут существовать сами по себе. Вы можете взять их с одного объекта и положить на другой. Объедините это с тем фактом, что все функции массива по контракту зависят только от объекта, имеющего свойство length, и вы поймете, почему это решение работает. - person Stijn de Witt; 19.09.2015

Как указал Арун, arguments не является массивом

Вам нужно будет преобразовать в массив

var optionalParameter = [].shift.apply(arguments);

person Clyde Lobo    schedule 11.11.2013
comment
В исходном ответе Аруна не было альтернативного решения. Он был добавлен позже - person Clyde Lobo; 11.11.2013

Это не причудливо, но лучшим решением для удаления первого аргумента без побочного эффекта (без добавления дополнительного аргумента, как shift), вероятно, будет

  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];

Пример :

function f(a, b, c, d) {
  for (var i=0;i<arguments.length;i++) arguments[i]=arguments[i+1];
  console.log(a,b,c,d); 
}
f(1,2,3,4); // logs 2,3,4,undefined
person Denys Séguret    schedule 11.11.2013
comment
После запуска вашего кода arguments.length === 4. Я думаю, что вы должны закончить работу, установив значение arguments.length-1 после цикла for. - person Stijn de Witt; 19.09.2015