如果我调用的 JS 方法的参数多于定义接受的参数,会发生什么?

IT技术 javascript function arguments attachevent
2021-03-09 20:58:40

我想知道常规的全系列 JS 开发人员(我)定义的函数,以及预定义的 DOM 方法。就像如果我尝试attachEvent使用 WHATWG 的签名调用 IE 会发生什么addEventListener例如,

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

具体来说,请注意false. 即使attachEvent方法的签名只调用两个参数,那会不会有什么问题?

谢谢。

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

foo(1, 2, true);
5个回答

JavaScript 没有固定参数列表的概念。对于您自己的函数,您始终可以指定任意数量的参数,并根据需要传入任意类型的参数。

对于与本机代码相关的内置函数,它取决于.

你问它取决于什么:

我们来看看ECMA-262

第 15 节关于内置(不要与主机混淆)函数的一般情况

除非在特定函数的描述中另有规定,如果本节中描述的函数或构造函数被赋予的参数少于指定函数所需的参数,则该函数或构造函数的行为应完全像它已被赋予足够的附加参数一样,每个这样的参数是未定义的值。

好吧。如果我传入的参数比需要的少,这取决于函数本身的规范(向下滚动第 15 节以找到每个内置函数的规范)。

除非在特定函数的描述中另有说明,如果本子句中描述的函数或构造函数被赋予的参数多于指定的函数允许的参数,则调用会评估额外的参数,然后函数将其忽略。然而,一个实现可以定义与这些参数相关的实现特定行为,只要该行为不是简单地基于额外参数的存在而引发的 TypeError 异常。

传入太多参数不应该引发 TypeError。但它仍然可能引发其他错误。同样,这取决于您谈论的功能。

你在明确地谈论 DOM 而不是内置函数。老实说,我找不到规范的相应部分。ECMA 规范比 w3 网站更容易阅读。

所以 DOM 函数将是宿主函数而不是内置函数,对吗?
2021-04-22 20:58:40
Soooo 基本上函数会忽略额外的参数,除非你处理它们
2021-04-26 20:58:40
对,那是正确的。DOM 是宿主对象/函数。ECMA 规范说“宿主对象:宿主环境提供的对象来完成 ECMAScript 的执行环境”。DOM 不是 JavaScript 本身的一部分。
2021-05-04 20:58:40

不会痛。你甚至可以调用一个参数少于它需要的函数,只要函数代码有几个未定义的值就可以了。

我只是不确定当您处理[native code]DOM 方法的已编译“ 时,事情是否会变得更加僵化
2021-05-09 20:58:40

我遇到了这个重要但古老的问题;我希望与它分享我的实验对后代有益:

  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

“类数组”意味着参数具有长度属性和从零开始索引的属性,但它没有 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;
}
我从 MDN 链接中拿了这个例子来简单地展示什么是可能的。我毫不怀疑该功能有更好的解决方案myConcat=)
2021-04-19 20:58:40
就用[].slice.call(arguments, 1).join(separator)
2021-05-04 20:58:40
是的,我知道这适用于原生 JS 函数。但是[compiled code]DOM 方法的“ ”呢,尤其是在 IE 中?
2021-05-08 20:58:40

我认为除非您明确处理隐式参数数组,否则它不会搞砸任何事情。你为什么要这样做?

我想它必须与接受其他函数作为参数的函数很常见。例如,内置的 Array.Prototype.forEach() 方法将尝试将三个参数传递给传递的函数,即使您将其定义为仅接受一两个参数(在大多数情况下也是如此)。
2021-05-10 20:58:40