rest参数 设置JavaScript函数的默认参数值




rest参数 (17)

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!!!

我希望JavaScript函数具有可选参数,我将其设置为默认值,如果未定义该值,则使用该参数。 在Ruby中你可以这样做:

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

这适用于JavaScript吗?

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

默认参数值

使用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

默认值表达式

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

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

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

f(1) === 50

正如 - http://es6-features.org/#DefaultParameterValues所引用的那样


function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

如果delete_after的值不是falsey值,则将其指定为delete_after ,否则它将分配字符串"my default here" 。 有关更多详细信息,请查看Doug Crockford对该语言的调查,并查看操作员部分

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

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

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 throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}

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

这个例子来自这里


如果您使用的是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

在上面的语法中,使用了OR运算符。 OR运算符总是返回第一个值,如果它可以转换为true如果它不返回righthandide值。 在没有相应参数的情况下调用函数时,JS引擎将参数变量(在我们的示例中为bar )设置为undefinedundefined然后转换为false,因此OR运算符返回值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的显式比较。

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

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

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

如果不存在或undefined这将把delete_after设置为false 。 你今天可以使用像这样的ES6功能,如Babel等转发器。

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


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

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

只是工作。

参考: 默认参数 - MDN

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

您还可以通过解构模拟默认命名参数

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

预ES2015

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

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

该解决方案适用于js:

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

如果由于某种原因你不在 ES6上并使用lodash这是通过_.defaultTo方法的默认函数参数的_.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 ,则将设置默认值


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

ES5:大多数给定的答案对我来说都不够好,因为在某些情况下我可能需要将0nullundefined等假值传递给函数。 要确定参数是否未定义,因为这是我传递的值而不是未定义的,因为根本没有定义,我这样做:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}

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


如果要使用最新的ECMA6语法,请使用此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

它被称为default function parameters 。 如果没有传递值或未定义,它允许使用默认值初始化形式参数。 注意 :它不适用于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


根据语法

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

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


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

function myfunc(a,b=10)

但请注意,它不能跨浏览器一致地工作。 对我来说,它在我的桌面上使用chrome,但在android上没有使用chrome。 如上所述,更安全的选择是 -

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

这个答案的意图不是重复相同的解决方案,而是其他人已经提到的,但是要告知函数定义中的参数赋值可能适用于某些浏览器,但不依赖于它。







default-parameters