我希望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是假的,所以x||11的结果是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!==未定义?x:11比更常见的成语x||11

默认值表达式

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

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

其他回答

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

如果delete_after的值不是假值,则将其赋值给delete_aafter,否则将赋值字符串“我的默认值”。有关更多详细信息,请查看DougCrockford的语言调查,并查看操作员部分。

如果要传入假值,即false、null、undefined、0或“”,则此方法不起作用。如果需要传入假值,则需要使用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 pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 
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!!!

根据语法

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

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

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

function myfunc(a,b=10)

但要注意,它在不同浏览器之间并不一致。对我来说,它在我的桌面上运行,但在android上不运行。更安全的选择,正如上面提到的那样-

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

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