为 JavaScript 函数设置默认参数值

Set a default parameter value for a JavaScript function

提问人:Tilendor 提问时间:5/22/2009 最后编辑:Kamil KiełczewskiTilendor 更新时间:2/14/2023 访问量:1450019

问:

我希望 JavaScript 函数具有可选参数,我设置了默认值,如果未定义值,则使用这些参数(如果传递了值,则忽略这些参数)。在 Ruby 中,你可以这样做:

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

这在 JavaScript 中有效吗?

function read_file(file, delete_after = false) {
  // Code
}
JavaScript 函数 参数 default-parameters

评论

2赞 Azhar Uddin Sheikh 11/30/2022
从这个会起作用ES6function read_file(file, delete_after=false){};

答:

633赞 Russ Cam 5/22/2009 #1
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

如果它不是值,则分配给 的值,否则它将分配字符串 .有关更多详细信息,请查看 Doug Crockford 对该语言的调查,并查看运算符部分delete_afterdelete_after"my default here"

如果要传入 falsey 值,即 、 、 或 ,则此方法不起作用。如果您需要传入虚假值,则需要使用 Tom Ritter 答案中的方法。falsenullundefined0""

在处理函数的多个参数时,允许使用者在对象中传递参数参数,然后将这些值与包含函数默认值的对象合并通常很有用

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

要使用

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 

评论

123赞 Tom Ritter 5/22/2009
我觉得这还不够,因为我可能想传入 false。
54赞 Russ Cam 5/22/2009
我发现它在大多数情况下都足够了
54赞 jinglesthula 11/1/2012
因为它不适用于虚假值,所以它可能会造成维护噩梦。在有更可靠的方法的情况下,以前总是传递真实值并突然失败的代码突然失败,这些代码可能应该避免。
2赞 Ayush 11/28/2012
在这种情况下,为什么没有得到表达式的布尔结果?delete_afterdelete_after || "my default value"
4赞 Mark Brackett 3/27/2016
或者,您可以默认为一个 falsey 值 - 这通常是一个很好的默认值(例如,bool 为 false,字符串为 emptystring,数字为 0 等) - 在这种情况下,传入的内容并不重要。
3559赞 Tom Ritter 5/22/2009 #2

ES6/ES2015开始,默认参数在语言规范中。

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

只是工作。

参考:默认参数 - MDN

默认函数参数允许在未传递未定义的情况下使用默认值初始化形式参数。

在 ES6 中,您可以通过解构来模拟默认的命名参数

// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
    // Use the variables `start`, `end` and `step` here
    ···
}

// sample call using an object
myFor({ start: 3, end: 0 });

// also OK
myFor();
myFor({});

ES2015之前

有很多方法,但这是我的首选方法——它允许你传递任何你想要的东西,包括 false 或 null。(typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}

评论

229赞 Camilo Martin 9/2/2012
您也可以将其封装为:然后您可以将其称为function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }a = defaultFor(a, 42);
7赞 Sampo Sarrala - codidact.org 11/3/2012
@SiPlus,您在尝试使用对象时免费获得了额外的引用错误:p即使它可能适用于某些浏览器并且可能更快,它仍然是一个对象,并且是对原始类型的引用,它试图告诉这里什么都没有,甚至没有.简而言之,这两种情况都在这里:JavaScript/Reference/Global_Objects/undefinedundefinednullundefinednull
10赞 Dziamid 5/17/2013
如果检查对象的属性,则为冗余。 这不会引发引用错误,并且简洁明了。typeoffunction foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }
12赞 Daddy32 12/9/2014
我知道这真的很小,但我不喜欢你如何分配以及这些参数不是未定义的。此外,对于未来的维护者来说,条件有点复杂的三元运算符可能很难阅读。我更喜欢以下语法: - 没有不必要的分配,而且更容易阅读。a = ab = bif (typeof a == 'undefined') a = 42
13赞 Abe Voelker 5/22/2015
有什么理由使用吗?这样做似乎更简单.另外,如果你拼写错误,而不是把它放在一个字符串中,你会得到一个引用错误。typeofa === undefinedundefined
158赞 TJ L 5/22/2009 #3

我个人觉得这样简单的东西更简洁、更易读。

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 

评论

6赞 andersand 8/16/2014
更新:如果您已经在使用下划线 .js,我发现使用 .使用此答案中所示的全局命名空间被许多人认为是一种不好的做法。如果不想使用下划线,您也可以考虑为这个常见任务(例如)滚动自己的实用程序,但我迟早会使用下划线,反正重新发明轮子是没有意义的。_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});util.default(arg, "defaul value")
2赞 4/22/2015
我实际上推荐这个,我使用它并称它为“por”,代表“参数或”
2赞 OsamaBinLogin 10/20/2015
不要说 typeof arg == 'undefined',而是说 arg === undefined
3赞 Alnitak 11/16/2015
@OsamaBinLogin您所说的对于当前的 JS 是正确的 - 旧的测试仍然存在,因为在某些浏览器上,它曾经可以用其他值覆盖,从而导致测试失败。undefined
3赞 Mr. Lance E Sloan 6/15/2017
@Alnitak:仍然可以覆盖。因此,使用 和 仍然是一个好主意。undefinedtypeof'undefined'
68赞 Felix Kling 5/29/2015 #4

在 ECMAScript 6 中,您实际上将能够准确地编写您拥有的内容:

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

这将设置为 if it is not present 或 。你现在可以在像 Babel 这样的转译器上使用像这样的 ES6 功能。delete_afterfalseundefined

有关更多信息,请参阅 MDN 文章

评论

1赞 Adriano Resende 7/8/2015
正在等待浏览器获取 ECMAScript 6
1赞 harryg 7/9/2015
巴别塔会把它翻译成什么?
2赞 Felix Kling 7/9/2015
@harryg:babeljs.io/repl/......
2赞 freemanoid 7/10/2015
以下是 ES6 的兼容性表 kangax.github.io/compat-table/es6/#default_function_parameters 很遗憾,尚不支持此语法。
0赞 ArtOfWarfare 6/5/2016
Edge14 以及当前的 Chrome 和 Opera 现在都支持它,以及去年的 FF......现在只是在等待 Safari,它在当前的测试版中支持它,所以希望在 ~4 个月内所有浏览器的最新版本都能支持它。然后,您只需要等待您的用户实际更新他们的浏览器(或推动他们这样做)。
10赞 jshbrmn 10/7/2015 #5

作为更新...使用 ECMAScript 6,您可以在函数参数声明中设置默认值,如下所示:

function f (x, y = 7, z = 42) {
  return x + y + z
}

f(1) === 50

引用者 - http://es6-features.org/#DefaultParameterValues

评论

13赞 user 11/6/2015
这个答案没有用,因为它是重复的
11赞 Martin Wantke 11/16/2015 #6

只需使用 undefined 的显式比较即可。

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
16赞 Zsolt Takács 11/16/2015 #7

该解决方案在 JS 中对我有用:

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

评论

4赞 Dmitri Pavlutin 12/20/2015
如果 是 或 会发生什么?对于这些情况,它将无法正常工作。delete_after0null
0赞 Rutrus 2/1/2017
@StephanBijzitter,只有在某些情况下才是正确的。但是,如果您只想让默认值取消设置值,则不起作用,因为 0 或 null !=== false。
0赞 Stephan Bijzitter 2/1/2017
@Rutrus:我听不懂你刚才说的话。
9赞 vivek 5/19/2016 #8

作为一个长期C++开发人员(Web开发的新手:)),当我第一次遇到这种情况时,我在函数定义中做了参数分配,就像问题中提到的一样,如下所示。

function myfunc(a,b=10)

但请注意,它不能在浏览器之间一致地工作。对我来说,它可以在我桌面上的 chrome 上运行,但在 android 上的 chrome 上运行。 正如上面许多人提到的,更安全的选择是——

    function myfunc(a,b)
    {
    if (typeof(b)==='undefined') b = 10;
......
    }

这个答案的目的不是重复其他人已经提到的相同解决方案,而是告知函数定义中的参数分配可能在某些浏览器上有效,但不要依赖它。

评论

3赞 DiMono 7/19/2016
函数定义中的分配在 IE 11 中也不起作用,IE 11 是 Windows 8.1 的最新版本。
1赞 gcampbell 9/18/2016
如果有人想知道 ES6 语法,其他答案中也有指向兼容性表的链接。function myfunc(a,b=10)
-3赞 Muhammad Awais 7/19/2016 #9

是的,这将在 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赞 Gert van den Berg 5/11/2017
它目前不是便携式的......IE浏览器...developer.mozilla.org/en/docs/Web/JavaScript/Reference/......(这是一个重复的答案......
8赞 Steven Johnston 8/3/2016 #10

对于有兴趣让代码在 Microsoft Edge 中工作的人,请不要在函数参数中使用默认值。

function read_file(file, delete_after = false) {
    #code
}

在该示例中,Edge 将抛出错误“Expecting ')'”

为了解决这个问题

function read_file(file, delete_after) {
  if(delete_after == undefined)
  {
    delete_after = false;
  }
  #code
}

截至 2016 年 8 月 8 日,这仍然是一个问题

33赞 Thalaivar 10/16/2016 #11

默认参数值

使用 ES6,您可以执行与设置函数参数默认值相关的最常见的习惯用语之一。我们多年来这样做的方式应该看起来很熟悉:JavaScript

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

这种模式最常用,但当我们传递这样的值时是危险的

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

为什么?因为 和 所以 ,不是直接传入 0。为了解决这个问题,有些人会更详细地写支票,如下所示:0 is falsyx || 11 results in 11

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

我们现在可以检查一个不错的有用语法,以简化默认值对缺失参数的分配:ES6

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11在函数中,声明更像是更常见的成语x !== undefined ? x : 11x || 11

默认值表达式

Function默认值可以不仅仅是像 31 这样的简单值;它们可以是任何有效的表达式,甚至是:function call

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

正如你所看到的,默认值表达式是延迟计算的,这意味着它们只在需要时运行,即当参数的参数被省略或未定义时。

默认值表达式甚至可以是内联函数表达式调用,通常称为立即调用的函数表达式:(IIFE)

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42
5赞 Sachin Kumar 10/16/2017 #12

根据语法

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

您可以定义形式参数的默认值。 并使用 typeof 函数检查未定义的值。

12赞 Doug Coburn 10/16/2017 #13

我强烈建议在 javascript 中使用默认参数值时要格外小心。当与高阶函数(如 、 和 )结合使用时,它通常会产生错误。例如,请考虑以下代码行:forEachmapreduce

['1', '2', '3'].map(parseInt); // [1, NaN, NaN]

parseInt 具有可选的第二个参数 radix,但映射具有三个参数的调用:(elementindexarray)。function parseInt(s, [=10])parseInt

我建议您将所需的参数与可选/默认值参数分开。如果您的函数接受 1、2 或 3 个没有默认值的必需参数,请将它们作为函数的位置参数,则任何可选参数都应作为单个对象的命名属性。如果您的函数需要 4 个或更多,那么通过单个对象参数的属性提供所有参数可能更有意义。

在你的情况下,我建议你像这样编写你的deleteFile函数:(根据的评论编辑)...instead

// unsafe
function read_file(fileName, deleteAfter=false) {
    if (deleteAfter) {
        console.log(`Reading and then deleting ${fileName}`);
    } else {
        console.log(`Just reading ${fileName}`);
    }
}

// better
function readFile(fileName, options) {
  const deleteAfter = !!(options && options.deleteAfter === true);
  read_file(fileName, deleteAfter);
}

console.log('unsafe...');
['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);

console.log('better...');
['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);

运行上述代码片段说明了潜伏在未使用参数的默认参数值后面的危险。

评论

1赞 instead 1/27/2019
这个“更好的解决方案”是相当不可读的。我宁愿建议检查变量类型,否则抛出异常。另外,如果使用 map/foreach 等方法,请谨慎使用它们并使用匿名函数包装调用的函数。typeof deleteAfter === 'bool'['1', '2', '3'].map((value) => {read_file(value);})
0赞 Doug Coburn 1/27/2019
这是一个很好的观点。我试图避免在我的代码片段中使用库,但这个成语在纯 javascript 中非常混乱。就个人而言,我会使用 lodash 的方法来检索 deleteAfter。抛出例外情况也可能是一个很好的谨慎措施。我不喜欢设计要求调用者“谨慎使用”的方法。谨慎是函数的责任,而不是调用者的责任。最终行为应遵循最小意外原则。gettypeof 'deleteAfter' !== 'bool'
0赞 instead 1/27/2019
我同意,该方法不应该以这种方式编写,调用它可能会破坏其行为。但请记住,函数就像模型,调用方就像控制器。模型应负责数据处理。函数(方法)应该期望数据,可以以错误的方式传递并处理它。这就是为什么检查参数类型并抛出异常是最好的方法。即使它更复杂。但它仍然可以让你免于挠头并继续问......为什么它不起作用?!然后。。。为什么它有效?!
6赞 Tính Ngô Quang 6/8/2018 #14
function helloWorld(name, symbol = '!!!') {
    name = name || 'worlds';
    console.log('hello ' + name + symbol);
}

helloWorld(); // hello worlds!!!

helloWorld('john'); // hello john!!!

helloWorld('john', '(>.<)'); // hello john(>.<)

helloWorld('john', undefined); // hello john!!!

helloWorld(undefined, undefined); // hello worlds!!!
5赞 dutta 7/1/2018 #15

function throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}

这里 foo() 是一个函数,它有一个名为 argValue 的参数。如果我们没有在这里的函数调用中传递任何内容,那么将调用函数 throwIfNoValue(),并将返回的结果分配给唯一的参数 argValue。这就是函数调用可以用作默认参数的方式。这使得代码更加简化和可读。

这个例子是从这里取来的

6赞 BlackBeard 7/5/2018 #16

如果要使用最新的 ECMA6 语法,请使用此选项:

function myFunction(someValue = "This is DEFAULT!") {
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

它被称为默认函数参数。它允许在未传递值或未定义的情况下使用默认值初始化形式参数。注意:它不适用于 Internet Explorer 或较旧的浏览器。

为了获得最大的兼容性,请使用以下命令:

function myFunction(someValue) {
  someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

这两个函数具有完全相同的行为,因为每个示例都依赖于这样一个事实,即如果在调用该函数时未传递参数值,则参数变量将是。undefined

评论

1赞 MagicLAMP 11/16/2018
注意:如@BlackBeard所说,function(param=value)不适用于IE。使用兼容版本。
7赞 Willem van der Veen 8/8/2018 #17

如果正在使用,则可以通过以下方式设置默认参数:ES6+

function test (foo = 1, bar = 2) {
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

如果需要语法,可以通过以下方式进行操作:ES5

function test(foo, bar) {
  foo = foo || 2;
  bar = bar || 0;
  
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

在上面的语法中,使用了运算符。运算符始终返回第一个值,如果可以转换为,则返回右侧值。当调用函数时没有相应的参数时,参数变量(在我们的示例中)由 JS 引擎设置为。 然后转换为 false,因此运算符返回值 0。ORORtruebarundefinedundefinedOR

6赞 Angel Politis 8/12/2018 #18

ES6:正如大多数答案中已经提到的,在 ES6 中,您可以简单地初始化一个参数和一个值。


ES5:大多数给出的答案对我来说都不够好,因为在某些情况下,我可能不得不将错误的值(例如 和 )传递给函数。为了确定参数是否未定义,因为这是我传递的值,而不是由于根本没有定义而未定义,我这样做:0nullundefined

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
0赞 Muhammad Rizwan 9/25/2018 #19
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。这种方法在编程上看起来并不吸引人,但具有向后兼容性

评论

0赞 ggorlen 6/18/2022
用。 已损坏(例如,为 true)。这并没有给现有的答案增加太多,而且JS近年来确实支持默认参数,所以我建议将其作为Python代码的最佳等价物,并使用转译器进行向后兼容。此外,显式调用函数和不传递参数是有区别的,所以如果你想要真正的全等,我也会检查参数的长度。=== undefined==null == undefinedundefined
2赞 esewalson 9/28/2018 #20

是的,这称为默认参数

默认函数参数允许在未传递值或未定义的情况下使用默认值初始化形式参数。

语法:

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

描述:

函数的参数默认为 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
4赞 Akrion 10/10/2018 #21

如果由于某种原因您不在 ES6 上并且正在使用 lodash,以下是通过 _.defaultTo 方法默认函数参数的简明方法:

var fn = function(a, b) {
  a = _.defaultTo(a, 'Hi')
  b = _.defaultTo(b, 'Mom!')

  console.log(a, b)
}

fn()                 // Hi Mom!
fn(undefined, null)  // Hi Mom!
fn(NaN, NaN)         // Hi Mom!
fn(1)                // 1 "Mom!"
fn(null, 2)          // Hi 2
fn(false, false)     // false false
fn(0, 2)             // 0 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

如果当前值为 NaNnullundefined,则将设置默认值

5赞 Alireza 1/18/2019 #22

是的,ES6 完全支持使用默认参数:

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

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

但在 ES5 之前,您可以轻松地做到这一点:

function read_file(file, delete_after) {
  var df = delete_after || false;
  // Code
}

这意味着如果值存在,则使用该值,否则,在执行相同操作后使用第二个值......||

注意:如果你把一个值传递给 ES6,即使这个值是假的,它们之间也有很大的区别,它将被替换为新值,比如 or ...但是只有当传递的值是真实的时,ES5 才会被替换,那是因为工作方式......null""||

1赞 Aman Pandey 6/13/2019 #23

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

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

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

这样,就很容易扩展参数,而不必担心参数长度不匹配。

-1赞 new Q Open Wid 7/17/2019 #24

答案是肯定的。事实上,有许多语言支持默认参数。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 中不起作用。请参阅文档。因此,对于IE,您必须使用“在函数顶部定义变量”方法。默认参数在 IE 中不起作用。

评论

1赞 ggorlen 6/18/2022
这里的 Python 代码无效,JS 代码没有多大意义。函数中包含变量的变量与默认值不同,因为调用方实际上无法覆盖该值。所以我不确定这些有什么关系。false
4赞 jave.web 10/18/2019 #25

未来之声

将来,您将能够将一个对象“传播”到另一个对象(截至 2019 年,Edge 不支持!) - 演示如何将其用于不错的默认选项,无论顺序如何:

function test(options) {
    var options = {
       // defaults
       url: 'defaultURL',
       some: 'somethingDefault',
       // override with input options
       ...options
    };
    
    var body = document.getElementsByTagName('body')[0];
    body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

MDN 参考编号: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

...同时 Edge 支持的是 Object.assign()(IE 没有,但我真的希望我们可以将 IE 抛在后面:))

同样,你可以这样做

    function test(options) {
        var options = Object.assign({
           // defaults
           url: 'defaultURL',
           some: 'somethingDefault',
        }, options); // override with input options
        
        var body = document.getElementsByTagName('body')[0];
        body.innerHTML += '<br>' + options.url + ' : ' + options.some;
    }
    test();
    test({});
    test({url:'myURL'});
    test({some:'somethingOfMine'});
    test({url:'overrideURL', some:'andSomething'});
    test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

编辑:由于关于选项的注释 - 在函数的其余部分使用常量选项的问题实际上不是你不能这样做,只是你不能在它自己的声明中使用常量变量 - 你必须将输入命名调整为类似const

function test(input_options){
   const options = {
     // defaults
     someKey:    'someDefaultValue',
     anotherKey: 'anotherDefaultValue',

     // merge-in input options
     ...input_options
   };

   // from now on use options with no problem
}

评论

0赞 frank-dspeed 12/13/2019
问题是你通常不想这样做,因为这将重新分配已经定义的选项,但你可以将它与另一个合法的变量一起使用。
0赞 frank-dspeed 12/13/2019
function test(options) { /* 定义了 Options,如果使用 const options = {} now*/ },它会抛出错误
0赞 frank-dspeed 12/14/2019
不,不是全局的,当你创建一个函数时,你作为参数名称选项传入,然后在函数内部定义了选项,在函数中定义了{} opt,你不能在该函数中使用常量opt,那么这很糟糕,因为如果你经常这样做,你会做变量重新分配,它看起来像你的一般模式,这是一个问题
0赞 jave.web 12/16/2019
@google-frank-dspeed啊,你是说你做不到吗?这肯定是行不通的,因为你会在声明之前使用 const 变量 - 你必须调整 -function(opt){ const opt = /*some merging*/; }function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
1赞 jave.web 12/16/2019
@google-frank-dspeed 无论如何,更多的新人可能会对此感到好奇,所以我添加了如何编辑:)的代码因此,感谢您为其他人指出这一点:)
3赞 Shivang Gupta 12/19/2019 #26

只是为了展示我的技能(笑),即使没有命名参数,也可以编写上述函数,如下所示:

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';
    ...
}
3赞 Kamil Kiełczewski 6/30/2020 #27

是 - 证明:

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);

2赞 maxxioso 5/4/2021 #28

我注意到一些答案提到使用默认参数不能移植到其他浏览器,但公平地说,您可以使用像 Babel 这样的转译器将您的代码转换为对现代 JS 功能支持有限的浏览器的 ES5 语法。

所以这个:

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赞 Engr.Aftab Ufaq 7/26/2021 #29
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 6/18/2022
这并没有真正为现有答案增加任何新内容。