为JavaScript函数设置默认参数值

我想要一个JavaScript函数有可选的参数,我设置了一个默认值,如果没有定义值会被使用。 在Ruby中,你可以这样做:

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

这是否工作在JavaScript?

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

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

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

只是工作。

参考: 默认参数 – MDN

如果没有值undefined被传递,默认的函数参数允许使用默认值初始化forms参数。

您也可以通过解构模拟默认的命名参数 :

 // 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 ··· } 

Pre ES2015

有很多方法,但这是我首选的方法 – 它可以让你通过任何你想要的,包括false或null。 ( typeof null == "object"

 function foo(a, b) { a = typeof a !== 'undefined' ? a : 42; b = typeof b !== 'undefined' ? b : 'default_b'; ... } 
 function read_file(file, delete_after) { delete_after = delete_after || "my default here"; //rest of code } 

如果delete_after的值不是falsey ,则将其赋值给delete_after的值,否则将string赋值为"my default here" 。 有关更多详细信息,请查看Doug Crockford对语言的调查,并查看有关运营商的部分 。

如果你想传递一个错误的值,例如falsenullundefined0或者"" ,这种方法是行不通的。 如果你需要通过falsey的值,你需要使用Tom Ritter的答案中的方法。

在处理函数的许多参数时,允许使用者将对象的parameter passing给参数,然后这些值与包含该函数的默认值的对象合并

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

我发现这样简单,更简洁和可读的个人。

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

在ECMAScript 6中,您实际上可以正确地编写您所拥有的内容:

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

如果不存在或undefined则将delete_after设置为false 。 你现在可以像使用Babel这样的转发器,使用像这样的ES6function。

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

默认参数值

使用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 is falsy ,所以x || 11 results in 11 x || 11 results in 11 ,而不是直接通过0.为了解决这个问题,有些人会把这个检查写得更加详细,就像这样:

 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 : 11 x !== undefined ? x : 11比成语更普遍x || 11 x || 11

默认值expression式

Function默认值可以不只是简单的值,如31; 它们可以是任何有效的expression式,甚至可以是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 

正如你所看到的,默认值expression式是懒惰的评估,意味着它们只在需要的时候运行,也就是说,当一个参数的参数被省略或者是未定义的。

默认值expression式甚至可以是内联函数expression式调用 – 通常称为立即调用函数expression式(IIFE)

 function foo( x = (function(v){ return v + 11; })( 31 ) ) { console.log( x ); } foo(); // 42 

这个解决scheme在js中为我工作:

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

只要使用明确的比较undefined。

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

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

 function myfunc(a,b=10) 

但是要注意,它在浏览器中不能一致地工作。 对我来说,它工作在我的桌面上的铬,但没有在Android上的铬工作。 更安全的select,正如上面提到的许多是 –

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

这个答案的意图不是重复相同的解决scheme,其他人已经提到过,而是通知函数定义中的参数赋值可能在某些浏览器上工作,但不要依赖它。

作为一个更新…与ECMAScript 6,你可以在函数参数声明最后设置默认值,如下所示:

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

正如引用 – http://es6-features.org/#DefaultParameterValues

对于有兴趣在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日,这仍然是一个问题

在JavaScript中使用默认参数值时,我强烈build议您非常小心。 当与高级函数(如forEachmapreduce结合使用时,通常会产生错误。 例如,考虑下面这行代码:

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

parseInt有一个可选的第二个参数function parseInt(s, [ radix =10])但映射调用parseInt三个参数:( 元素索引数组 )。

我build议你分开你需要的参数forms的可选/默认值参数。 如果你的函数需要1,2或者3个没有默认值的必要参数,把它们作为函数的位置参数,任何可选参数都应该作为单个对象的命名属性。 如果你的函数需要4个或更多,也许通过单个对象参数的属性提供所有参数更有意义。

在你的情况下,我会build议你写这样的deleteFile函数:

 // 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 = false } = options || {}; // if null 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); 

根据语法

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

你可以定义forms参数的默认值。 并使用typeof函数检查未定义的值。

是的,这将在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