允许在Javascript中使用命名参数或位置参数

AKG*_*AKG 7 javascript parameter-passing ecmascript-6

我怎样才能有一个函数接受或者命名参数(foo({a: 'hello', b: 'it is me'}))位置参数(foo('hello', 'it is me'))?

我知道可以通过将对象传递给函数来模拟命名参数:

function foo(options) {
    options = options || {};
    var a = options.a || 'peanut'; // whatever default value
    var b = options.b || 'butter'; // whatever default value
    console.log(a, b);
}

// ES6 allows automatic destructuring
function foo({a = 'peanut', b = 'butter'} = {}) {
    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)

但这不允许我接受通过的位置论证.

我想使用ES6,但ES5的任何东西都可以.

Ber*_*rgi 4

首先,我真的建议坚持使用一种方法。正如你所说,使用命名”

function foo({a = 'peanut', b = 'butter'} = {}) {
    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)

位置参数:

function foo(a = 'peanut', b = 'butter') {
    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)

选择更适合您功能的一种,不要混合使用两者


如果出于某种原因您确实需要两者,则可以使用标准重载技术。仅当您的第一个位置参数不是对象时它才能正常工作。我建议使用以下习语之一:

function foo(a, b) { // positional is normal case
    if (arguments.length == 1 && typeof arguments[0] == "object")
        {a, b} = arguments[0];

    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)
function foo({a, b}) { // named is normal case
    if (arguments.length > 1 || typeof arguments[0] != "object")
        [a, b] = arguments;

    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)

如果你需要默认值,无论哪种方式都会变得丑陋:

function foo(a, b) {
    var opts = (arguments.length == 1 && typeof arguments[0] == "object")
      ? arguments[0]
      : {a, b};
    ({a = 'peanut', b = 'butter'} = opts);

    console.log(a, b);
}
Run Code Online (Sandbox Code Playgroud)