非常教程

JavaScript参考手册

函数 | Function

Default parameters

函数默认参数允许在没有值或undefined被传入时使用默认形参。

语法

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

描述

JavaScript 中函数的参数默认是undefined。然而,在某些情况下可能需要设置一个不同的默认值。这是默认参数可以帮助的地方。

以前,一般设置默认参数的方法是在函数体测试参数是否为undefined,如果是的话就设置为默认的值。下面的例子中,如果在调用multiply时,参数b的值没有提供,那么它的值就为undefined。如果直接执行a*b,函数会返回 NaN。但是第二行代码解决了这个问题:

function multiply(a, b) {
  b = (typeof b !== 'undefined') ?  b : 1;
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5

有了默认参数,我们不需要再在函数体内做不必要的检查。现在你可以在函数头将b的默认值置为1

function multiply(a, b = 1) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5

示例

传入 undefined vs 其他空值

在第二个调用中,即使第二个参数在调用时显式设置为undefined(虽然不是null或其他falsy值),但是num参数的值是默认值。

function test(num = 1) {
  console.log(typeof num);
}

test();          // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)

// test with other falsy values:
test('');        // 'string' (num is set to '')
test(null);      // 'object' (num is set to null)

调用时解析

在函数被调用时,参数默认值会被解析,所以不像Python中的例子,每次函数调用时都会创建一个新的参数对象。

function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], not [1, 2]

这个规则对于函数和变量也是适用的。

function callSomething(thing = something()) {
 return thing;
}

function something() {
  return 'sth';
}

callSomething();  //sth

默认参数可用于后面的默认参数

已经遇到的参数可用于以后的默认参数:

function singularAutoPlural(singular, plural = singular + 's', 
                            rallyingCry = plural + ' ATTACK!!!') {
  return [singular, plural, rallyingCry]; 
}

//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural('Gecko');

//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural('Fox', 'Foxes');

//["Deer", "Deer", "Deer ... change."]
singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \
   petition the government for positive change.')

以下这个例子近似模拟了一些比较简单的情况,并说明了特殊情况是怎么被处理的。

function go() {
  return ':P';
}

function withDefaults(a, b = 5, c = b, d = go(), e = this, 
                      f = arguments, g = this.value) {
  return [a, b, c, d, e, f, g];
}

function withoutDefaults(a, b, c, d, e, f, g) {
  switch (arguments.length) {
    case 0:
      a;
    case 1:
      b = 5;
    case 2:
      c = b;
    case 3:
      d = go();
    case 4:
      e = this;
    case 5:
      f = arguments;
    case 6:
      g = this.value;
    default:
  }
  return [a, b, c, d, e, f, g];
}

withDefaults.call({value: '=^_^='});
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]


withoutDefaults.call({value: '=^_^='});
// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]

函数嵌套定义

在 Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30) 中引入。在函数体内的函数声明不能引用内部的默认参数,并且会在 SpiderMonkey 抛出一个ReferenceError(现在是 TypeError),参见bug 1022967。默认参数总是会被首先执行,而在函数体内部的函数声明会在之后生效。

// Doesn't work! Throws ReferenceError.
function f(a = go()) {
  function go() { return ':P'; }
}

位于默认参数之后非默认参数

在Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2)之前,以下代码会造成SyntaxError错误。这已经在bug 1022967中修复,并在以后的版本中按预期方式工作。参数仍然设置为从左到右,覆盖默认参数,即使后面的参数没有默认值。

function f(x = 1, y) { 
  return [x, y]; 
}

f(); // [1, undefined]
f(2); // [2, undefined]

有默认值的解构参数

你可以通过解构赋值为参数赋值:

function f([x, y] = [1, 2], {z: z} = {z: 3}) { 
  return x + y + z; 
}

f(); // 6

规范

Specification

Status

Comment

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Function Definitions' in that specification.

Standard

Initial definition.

ECMAScript Latest Draft (ECMA-262)The definition of 'Function Definitions' in that specification.

Living Standard

浏览器兼容性

Feature

Chrome

Edge

Firefox (Gecko)

Internet Explorer

Opera

Safari

Basic support

49

38 (14.14342)

15.0 (15.0)

No support

45

10

Parameters without defaults after default parameters

49

38 (14.14342)

26.0 (26.0)

No support

?

10

Destructured parameter with default value assignment

49

?

41.0 (41.0)

No support

?

?

Feature

Android

Android Webview

Edge

Firefox Mobile (Gecko)

IE Mobile

Opera Mobile

Safari Mobile

Chrome for Android

Basic support

No support

49

(Yes)

15.0 (15.0)

No support

No support

No support

49

Parameters without defaults after default parameters

No support

49

(Yes)

26.0 (26.0)

?

?

?

49

Destructured parameter with default value assignment

No support

?

?

41.0 (41.0)

?

?

?

?

JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络