声明函数时,可以为任意参数指定默认值,在已指定默认值的参数后可以继续声明无默认值参数。当调用函数时,如果没有为函数的默认参数传入值,则为其提供一个初始值。

  1. function makeRequest(url, timeout = 2000, callback) {
  2. // 函数的其余部分
  3. }

默认参数值对 arguments 对象的影响

arguments 对象在非严格模式下,有个特点:arguments 的值,永远与对应命名参数的值保持同步。也就是说改变了 arguments 的值会反映到参数的值上,改变了参数的值会反映到 argumetns 的值上。但是这一特点,在严格模式下就失效了。

当一个函数使用了默认参数,其对 arguments 的影响与在严格模式下一样。

默认参数的临时死区

与 let 声明类似,定义参数时会为每个参数创建一个新的标识符绑定,该绑定在初始化之前不可被引用,如果试图访问会导致程序抛出错误。当调用函数时,会通过传入的值或参数的默认值初始化该参数。

  1. function add(first, second = first) {
  2. return first + second;
  3. }
  4. console.log(add(1, 1));
  5. console.log(add(1));

调用 add(1, 1)add(1) 时实际上相当于执行以下代码来创建 frist 和 second 参数值:

  1. // 表示调用 add(1, 1)时的 JavaScript 代码
  2. let first = 1;
  3. let second = 1;
  4. // 表示调用 add(1) 时的 JavaScript 代码
  5. let first = 1;
  6. let second = first;

当初次执行函数 add() 时,绑定 first 和 second 被添加到一个专属函数参数的临时死区(与 let 的行为类型)。由于初始化 second 时 first 已经被初始化,所以它可以访问 first 的值,但是反过来就错了。

  1. function add(first = second, second) {
  2. return first + second;
  3. }
  4. console.log(add(1, 1));
  5. console.log(add(undefined, 1)); // 报错
  1. // 表示调用 add(1, 1)时的 JavaScript 代码
  2. let first = 1;
  3. let second = 1;
  4. // 表示调用 add(undefined, 1)时的 JavaScript 代码
  5. let first = second; // 当 frist 初始化时 second 尚未初始化,因此程序抛出错误。
  6. let second = 1;