Что произойдет, если я вызову метод JS с большим количеством параметров, чем определено для принятия?

Я хотел бы знать как для обычных функций JS, разработанных для всех разработчиков, так и для предопределенных методов DOM. Как то, что происходит, если я пытаюсь позвонить в IE attachEvent с подписью WHATWG addEventListener? Например,

elem.attachEvent('onbillgates\'mom', function(e){ this.mount(); }, false);

В частности, обратите внимание на false, Будет ли это путешествие что-нибудь, хотя attachEvent подпись метода требует только двух аргументов?

Благодарю.

function foo(FirstOf2, SecondOf2) {
  console.log(FirstOf2 + SecondOf2);
}

foo(1, 2, true);

6 ответов

Решение

В JavaScript нет концепции фиксированного списка параметров. Для своих собственных функций вы всегда можете указать столько параметров, сколько хотите, и передать столько, сколько хотите, какой бы тип вы ни выбрали.

Для встроенных функций, которые соответствуют нативному коду, это зависит.

Вы спросили, от чего это зависит:

Давайте посмотрим на ECMA-262

Раздел 15 о встроенных (не путать с хостом) функциях в целом

Если иное не указано в описании конкретной функции, если функции или конструктору, описанному в этом разделе, задается меньше аргументов, чем требуется для функции, функция или конструктор должны вести себя точно так, как если бы ей были предоставлены достаточные дополнительные аргументы, каждый таким аргументом является неопределенное значение.

Хорошо. Если я передам меньше аргументов, чем необходимо, это зависит от спецификации самой функции (прокрутите раздел 15 вниз, чтобы найти спецификацию для каждой встроенной функции).

Если иное не указано в описании конкретной функции, если функции или конструктору, описанному в этом разделе, дается больше аргументов, чем указано в функции, чтобы разрешить, дополнительные аргументы оцениваются вызовом и затем игнорируются функцией. Однако реализация может определять специфичное для реализации поведение, относящееся к таким аргументам, при условии, что такое поведение не вызывает исключение TypeError, которое основано просто на наличии дополнительного аргумента.

Передача слишком большого количества аргументов никогда не должна вызывать ошибку TypeError. Но все же это может вызвать другие ошибки. Опять же, это зависит от функции, о которой вы говорите.

Вы явно говорили о DOM, а не о встроенных функциях. Честно говоря, я не могу найти соответствующие части спецификации. Спецификацию ECMA намного легче читать, чем на веб-сайте w3.

Не повредит Вы даже можете вызывать функцию с меньшим количеством параметров, чем требуется, если код функции в порядке с несколькими неопределенными значениями.

Я столкнулся с этим важным, хотя и старым вопросом; и я надеюсь, что будущим поколениям будет полезно поделиться с ним моими экспериментами:

  1. Можно использовать argumentsобъект для доступа к аргументам функции, независимо от количества аргументов в сигнатуре функции.
    Стоит отметить, что это не относится к функциям стрелок:

function singleArg(x) {
  console.log(arguments);
}

singleArg(1, 2); // Called with 2 arguments
singleArg();     // Called with 0 arguments

// Results in an error, as 'arguments' isn't defined for arrow functions
((arg) => console.log(arguments))(1);

  1. В документации указано, чтоargumentsне совсемArray:

    "Подобно массиву" означает, что аргументы имеют свойство длины и свойства, проиндексированные с нуля, но не имеют встроенных методов массива, таких как forEach() и map().

    Следовательно, следующий код приводит к ошибке:

(function singleArg(x) {
  console.log(arguments); // This line works
  arguments.foreach(x => console.log(x)); // This causes an error
})(1, 2);

  1. При вызове функции с меньшим количеством аргументов, чем в ее сигнатуре, им присваивается undefined:

(function twoArgs(a, b) {
  console.log(`a: ${a}\nb: ${b}`);
})(1);

Попробуйте взглянуть на этот пост и, возможно, на этот.

От MDN:

arguments объект является локальной переменной, доступной во всех функциях; arguments как свойство Function больше не может быть использовано.

Вы можете обратиться к функции arguments в функции с помощью arguments объект. Этот объект содержит запись для каждого аргумента, переданного функции, индекс первой записи начинается с 0.

Вы можете использовать arguments объект, если вы вызываете функцию с более arguments чем официально объявлено о принятии. Этот метод полезен для функций, которым можно передавать переменное число аргументов.

function myConcat(separator) {
  var result = "";

  // iterate through non-separator arguments
  for (var i = 1; i < arguments.length; i++) {
    result += arguments[i] + separator;
  }

  return result;
}

The argumentsОбъект — это объект, подобный массиву, доступный внутри функций, который содержит значения аргументов, переданных этой функции.

Например, если функции передано 3 аргумента, вы можете получить к ним доступ следующим образом:

      arguments[0]; // first argument
arguments[1]; // second argument
arguments[2]; // third argument

Объект аргументов полезен для функций, вызываемых с большим количеством аргументов, чем официально объявлено, и называемых вариативными функциями. Более подробную информацию можно найти здесь.

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

Я не думаю, что это что-то испортит, если вы не имеете дело с массивом неявных аргументов. Почему ты это делаешь?

Другие вопросы по тегам