JavaScript函数中多个参数的默认参数

6

我有一个函数,它接受多个可选参数。目前,这个函数没有按照我期望的方式分配默认值。

var test1 = function(arg1, arg2, arg3, arg4) {

    arg1 = arg1 || "arg1";
    arg2 = arg2 || "arg2";

    var obj = {
      arg1: arg1,
      arg2: arg2,
      arg3: arg3,
      arg4: arg4
    };

    return(obj);

};

var obj1 = test1(arg3 = "notarg1", arg4 = "notarg2"); // Why are these values assigned to arg1 & arg2 instead of 3 & 4?

console.log(obj1);

我不理解这个。Javascript似乎忽略了我的(arg3 = "notarg1", arg4 = "notarg2")赋值,而是表现得好像(arg1 = "notarg1", arg2 = "notarg2", arg3 = undefined, arg4 = undefined)是我的输入。

  var test2 = function(arg1, arg2, arg3, arg4) {

    if (arg1 === null) {
      arg1 = "arg1";
    }
    if (arg2 === null || arg2 === "undefined") {
      arg2 = "arg2";
    }

    var obj = {
      arg1: arg1,
      arg2: arg2,
      arg3: arg3,
      arg4: arg4
    };

    return(obj);

  };

  var obj2 = test2(arg3 = "notarg1", arg4 = "notarg2")

  console.log(obj2);

我不确定是否值得包含这个内容。情况没有改变。


在MDN上有一篇关于默认参数的好文章。请注意,这是ECMAScript 2015的一个特性。 - RobG
你正在向函数发送两个参数,因此这些值将分配给返回对象的前两个属性。 - Azad
1
那些不是默认参数。你只是将赋值作为调用的参数。JavaScript 没有命名参数! - Bergi
2个回答

18

JavaScript没有为指定的参数在调用函数时命名的功能,因此这行代码:

var obj1 = test1(arg3 = "notarg1", arg4 = "notarg2");

它并不做你想象中的事情。它实际上是这样的:

arg3 = "notarg1";
arg4 = "notarg2";
var obj1 = test1("notarg1", "notarg2");

例如,函数调用中的arg3 = "notarg1"只是对变量进行赋值(在这种情况下,可能是一个隐式全局变量),而赋值运算符的工作方式是将值分配给变量,并且操作的结果是被分配的值。
要使用您的代码获取args 1和2的默认值,您必须指定undefined
var obj1 = test1(undefined, undefined, arg3, arg4);

在这里,你正在指定第1个和第2个参数,但是你给它们的值是falsey,因此你的函数arg1 = arg1 || "arg1"将采用"arg1"(arg2同理)。
如果你有超过三个参数,你可以考虑使用选项对象:
function test1(options) {
    var arg1 = options.arg1 || "arg1";
    var arg2 = options.arg2 || "arg2";
    var arg3 = options.arg3 || "arg3";
    var arg4 = options.arg4 || "arg4";

    console.log(arg1, arg2, arg3, arg4)
}

test({arg3: "notarg1", arg4: "notarg2"});

输出:
arg1,arg2,notarg1,notarg2

仅为完整起见,ES2015(也称为ES6)添加了默认参数值,但您仍然无法像您在问题中展示的那样调用函数。不过,ES2015语法确实简化了您函数中的代码。

// ES2015+
function test1(arg1 = "arg1", arg2 = "arg2", arg3, arg4) {
    // ....
}

然而,虽然在调用时所做的操作是相同的,但与某些语言中的特殊“名称匹配”功能不同,它仍然没有特殊的功能。


1
那么没有办法允许省略参数吗? - Eugene Brown
@GeeBrownit:不是那样的,但你可以传递一个选项对象。我刚刚添加了一点关于这个的内容。 - T.J. Crowder

3
更好的方法是将一个对象传递给函数,这样你就不必担心缺少参数。
var test1 = function(options) {

    var arg1 = options.arg1 || "arg1";
    var arg2 = options.arg2 || "arg2";
    ...
};

var obj1 = test1({ arg1: "notarg3", arg2: "notarg1" });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接