为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对语言的调查,并查看有关运营商的部分 。
如果你想传递一个错误的值,例如false
, null
, undefined
, 0
或者""
,这种方法是行不通的。 如果你需要通过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
对于有兴趣在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议您非常小心。 当与高级函数(如forEach
, map
和reduce
结合使用时,通常会产生错误。 例如,考虑下面这行代码:
['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