在 JavaScript 函数中跳过参数

问题描述 投票:0回答:9

我有这样的功能:

function foo(a, b, c, d, e, f) {
}

为了仅使用

f
参数调用此函数,我知道我应该这样做:

foo(undefined, undefined, undefined, undefined, undefined, theFValue);

有没有更简洁的方法来做到这一点?

javascript
9个回答
76
投票

这样的:

foo(undefined, undefined, undefined, undefined, undefined, arg1, arg2);

.等于:

foo(...Array(5), arg1, arg2);

. 或:

foo(...[,,,,,], arg1, arg2);

这样的:

foo(undefined, arg1, arg2);

.等于:

foo(...Array(1), arg1, arg2);

. 或:

foo(...[,], arg1, arg2);

这样的:

foo(arg1, arg2);

.等于:

foo(...Array(0), arg1, arg2);

. 或:

foo(...[], arg1, arg2);

25
投票

可以使用

apply

foo.apply(this, Array(5).concat([theFValue]));

在这种情况下,

5
是您要跳过的参数数量。

将其包装在函数中:

function call(fn, skipParams, parameter) {
    fn.apply(this, Array(skipParams).concat([parameter]));
}

call(foo, 5, theFValue);

但是,在那种情况下,

this
的范围是不同的,所以你可能也需要传递它:

function call(fn, skipParams, parameter, thisArg) {
    fn.apply(thisArg, Array(skipParams).concat([parameter]));
}

call(foo, 5, theFValue, this);

再说一次,这个实现只允许传递1个参数。让我们改进一下:

function call(fn, skipParams, parameters, thisArg) {
    fn.apply(thisArg, Array(skipParams).concat(parameters));
}

call(foo, 5, [theFValue, theGValue, theHValue], this);

这开始变得“有点”冗长了。它也不能很好地处理第一个参数之后丢失的参数,除非你想传递

undefined

call(foo, 5, [theFValue, theGValue, theHValue, undefined, theJValue], this);

或者,完全不同的东西:

var _ = undefined;
foo(_,_,_,_,_, theFValue);

更严肃的一点:

处理可选参数的最佳选择是更改处理参数的方式。简单地传递一个对象:

function foo(parameters){
    // do stuff with `parameters.a`, `parameters.b`, etc.
}

foo({c: 1, g: false});

这种方法没有前面例子中任何的缺点。


23
投票

处理可选参数的更好方法是传递一个您查找其属性的对象:

function foo(options) {
    var a = options.a,
        b = options.b,
        c = options.c,
        d = options.d,
        e = options.e,
        f = options.f;
}

foo({ f: 15 });

10
投票

跳过功能:

const skip = (num) => new Array(num);

跳过开始参数:

foo(...skip(4), f);

跳过结束参数:

foo(f, ...skip(4));

跳过中间参数:

foo(f, ...skip(4), f2);

4
投票

如果你将传递一个属性名称为 f 的对象,那么你可以使用 destructuring assignment 和 ES6 语法,如下所示:

function foo({ f }) {
  console.log(f);
}
    
foo({ g: 5, f: 10 });


3
投票

如果这是你想要经常做的事情,那么考虑一个简单的包装器:

function bar(f) {
    foo(undefined, undefined, undefined, undefined, undefined, f);
}

如果你只这样做一次,或者你想要随机排列参数,那么这种方法不是最好的。


2
投票

我提供了一些可以帮助你实现的方法,如下所示,

  1. 解构赋值(推荐)
  2. Optional_chaining

方法一:解构赋值

例子1

function Person(name, {id="007", age=-1, info={msg:null, mood:undefined}}) {
  return [name, id, age, info.msg, info.mood]
}

// 👇 Test Only
for (const [result, expected] of [
  [Person("Carson", {}), // If you don't need any options then must set "" or {}
    ["Carson", "007", -1, null, undefined]
  ],
  [Person("Aoo", {
    age: 29,
    info: {
      msg: "hello world"
    }
  }),
    ["Aoo", "007", 29, "hello world", undefined]
  ],
  [Person("Boo", {
    id: "003",
    info: {
      mood: "Happy"
    }
  }),
    ["Boo", "003", -1, null, "Happy"]
  ]
]) {
  console.log(JSON.stringify(result))
  console.log(JSON.stringify(result) === JSON.stringify(expected))
}

例二

const user = {
  id: 42,
  displayName: 'jdoe',
  fullName: {
    firstName: 'John',
    lastName: 'Doe'
  }
};

function userId({id}) {
  return id;
}

function whois({displayName, fullName: {firstName: name}}) {
  return `${displayName} is ${name}`;
}

console.log(userId(user)); // 42
console.log(whois(user));  // "jdoe is John"

👆 来自 object_destructuring search

Unpacking fields from objects passed as a function parameter

的源代码

方法二

使用Optional_chaining设置默认值

const val = obj ?? "default value" // if obj is undefined then val = default value
const val = obj?.msg // equal to obj.msg if {msg:...} exists in the obj. Otherwise, undefined

例如

/*
Assume your options is:
{
  id:"",
  info:{
    msg:"",
    mood: "",
  }
}
*/
function MyFunc(name, options = {}) {
  const id = options.id ?? "007"
  const msg = options.info?.msg ?? null
  const mood = options.info?.mood
  // ...
}

例子

function Person(name, options = {}) {
  const id = options.id ?? "007"
  const msg = options.info?.msg ?? null
  const mood = options.info?.mood
  return [name, id, msg, mood]
}


for (const [result, expected] of [
  [Person("Carson"),
    ["Carson", "007", null, undefined]
  ],
  [Person("Aoo", {
    info: {
      msg: "hello world"
    }
  }),
    ["Aoo", "007", "hello world", undefined]
  ],
  [Person("Boo", {
    id: "003",
    info: {
      mood: "Happy"
    }
  }),
    ["Boo", "003", null, "Happy"]
  ]
]) {
  console.log(JSON.stringify(result) === JSON.stringify(expected))
}

方法2.extend

如果想让IDE知道选项是什么,可以考虑使用下面的方法,

function PersonOptions(options={}) {
  this.id = options.id ?? "007"
  this.msg = options.info?.msg ?? null
  this.mood = options.info?.mood
}

function Person2(name, options = new PersonOptions()) {
  return [name, options.id, options.msg, options.mood]
}

for (const [result, expected] of [
  [Person2("Carson"),
    ["Carson", "007", null, undefined]
  ],
  [Person2("Aoo", new PersonOptions({
    info: {
      msg: "hello world"
    }
  })),
    ["Aoo", "007", "hello world", undefined]
  ],
  [Person2("Boo", new PersonOptions({
    id: "003",
    info: {
      mood: "Happy"
    }
  })),
    ["Boo", "003", null, "Happy"]
  ]
]) {
  console.log(JSON.stringify(result) === JSON.stringify(expected))
}


1
投票

对部分应用程序使用绑定:

function foo(a, b, c, d, e, f) {
    document.write(f);
}

function skip(f, n) {
    while (n--) {
        f = f.bind(null, undefined);
    }
    return f;
}

skip(foo, 5)('hallo');


1
投票

怎么样

function multiply(a = 2, b = 1) {
  return a * b;
}

console.log(multiply(undefined, 3));
// expected output: 6

如果你传递一个未定义的参数,它将使用定义中的默认值。

© www.soinside.com 2019 - 2024. All rights reserved.