为JavaScript函数设置默认参数值

2651

我想要一个JavaScript函数可以有可选参数,并且可以设置默认值,如果该值未定义则使用默认值(如果传递了值,则忽略默认值)。在Ruby中,您可以这样做:

def read_file(file, delete_after = false)
  # code
end

这个JavaScript代码可以运行吗?

function read_file(file, delete_after = false) {
  // Code
}

2
ES6 开始,这将起作用:function read_file(file, delete_after=false){}; - Azhar Uddin Sheikh
29个回答

3

是的 - 证明:

function read_file(file, delete_after = false) {
  // Code
  console.log({file,delete_after});
}



// TEST
read_file("A");
read_file("B",true);
read_file("C",false);


3

为了展示我的技能(哈哈),上面的函数甚至可以在没有命名参数的情况下编写,如下所示:

ES5及以上版本

function foo() {
    a = typeof arguments[0] !== 'undefined' ? a : 42;
    b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
    ...
}

ES6及以上

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}

2

是的,这被称为默认参数。

默认函数参数允许在没有传递值或未定义时,使用默认值初始化形式参数。

语法:

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

描述:

函数的参数默认值为undefined。但在某些情况下,设置不同的默认值会很有用。这就是默认参数可以帮助解决的问题。

以往,设置默认值的通用策略是在函数体内测试参数值并在它们为undefined时分配一个值。如果在调用中没有提供值,则其值将为undefined。您必须设置一个条件检查以确保参数不为undefined。

在ES2015中使用默认参数时,函数体中的检查不再必要。现在,您可以直接在函数头中放置默认值。

以下是差异的示例:

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

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


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

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

不同的语法示例:

填充未定义与其他假值:

即使在调用时明确设置了值,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)

在调用时进行评估:

默认参数在调用时进行评估,因此与其他一些语言不同,每次调用函数时都会创建一个新对象。

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

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


// This even applies to functions and variables
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.')

函数体内定义的函数:

在Gecko 33(Firefox 33 / Thunderbird 33 / SeaMonkey 2.30)中引入。在函数体内声明的函数无法在默认参数内引用,并会抛出一个ReferenceError错误(当前在SpiderMonkey中是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 777060中得到修复,并且在后续版本中按预期工作。参数仍然从左到右设置,即使有后面没有默认值的参数也会覆盖默认参数。

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

2
我注意到有些答案提到使用默认参数不可移植到其他浏览器,但公平的是要指出,您可以使用转译器(如Babel)将代码转换为ES5语法,以便在支持现代JS功能有限的浏览器中运行。

因此,这个:

function read_file(file, delete_after = false) {
  // Code
}

这将被转译为以下代码(在 Babel REPL 中尝试一下 -> https://babeljs.io/repl/):

"use strict";

function read_file(file) {

  var delete_after =
    arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
  //Code...

}

当然,如果您不打算使用转译,那么在函数体中设置默认参数就像其他人展示的那样也是完全可以的。


1

设置默认参数的另一种方法是使用参数对象映射,而不是直接使用参数。例如,

const defaultConfig = {
 category: 'Animals',
 legs: 4
};

function checkOrganism(props) {
 const category = props.category || defaultConfig.category;
 const legs = props.legs || defaultConfig.legs;
}

这样做可以轻松扩展参数,而不必担心参数长度不匹配。

1
export const getfilesize = (bytes, decimals = 2) => {
    if (bytes === 0){ 
        return '0 Bytes';
    }else{
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];

    }
}

1
这并没有为现有的答案增添任何新内容。 - ggorlen

0
def read_file(file, delete_after = false)
  # code
end

以下代码在这种情况下可能适用于ECMAScript 6(ES6)以及早期版本。

function read_file(file, delete_after) {
    if(delete_after == undefined)
        delete_after = false;//default value

    console.log('delete_after =',delete_after);
}
read_file('text1.txt',true);
read_file('text2.txt');

在语言中作为默认值时,当调用函数时跳过参数值时,在JavaScript中它被赋值为未定义(undefined)。这种方法在编程上看起来不太有吸引力,但是具有向后兼容性


使用 === undefined== 是有问题的(例如,null == undefined 是 true)。这并没有为现有答案增加太多内容,而且 JS 在最近几年中支持默认参数,因此我建议将其作为 Python 代码的最佳等价物,并使用转译器实现向后兼容性。另外,如果您想要真正的一致性,调用函数时显式地使用 undefined 和不传递参数之间存在差异,因此我还会检查参数的长度。 - ggorlen

-1

答案是肯定的。事实上,有许多语言支持默认参数。Python就是其中之一:

def(a, enter="Hello"):
   print(a+enter)

尽管由于括号的原因,这是Python 3代码,但函数中的默认参数在JS中也适用。

例如,在您的情况下:

function read_file(file, deleteAfter=false){
  console.log(deleteAfter);
}

read_file("test.txt");

但有时您真的不需要默认参数。

您可以在函数开始后定义变量,就像这样:

function read_file(file){
  var deleteAfter = false;
  console.log(deleteAfter);
}

read_file("test.txt");

在我的两个示例中,它们返回相同的结果。但有时它们确实很有用,例如在非常高级的项目中。
因此,总的来说,在JS中可以使用默认参数值。但这几乎与在函数开始后立即定义变量是一样的。然而,有时它们仍然非常有用。正如您可能已经注意到的那样,默认参数值比定义参数的标准方式少了1行代码。
编辑:这非常重要!这个方法在IE中不起作用。请参见documentation。因此,在IE中,您必须使用“在函数顶部定义变量”的方法。默认参数在IE中不起作用。

1
这里的Python代码无效,JS代码也不太合理。带有函数中变量的那个与默认值不同,因为调用者实际上无法覆盖“false”值。所以我不确定这些内容有何相关性。 - ggorlen

-3

是的,这在Javascript中可以工作。你也可以这样做:

function func(a=10,b=20)
{
    alert (a+' and '+b);
}

func(); // Result: 10 and 20

func(12); // Result: 12 and 20

func(22,25); // Result: 22 and 25

2
它目前不具备可移植性... IE... https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters#Browser_compatibility(而且这是一个重复的答案...) - Gert van den Berg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接