我有这样的功能:
function foo(a, b, c, d, e, f) {
}
为了仅使用
f
参数调用此函数,我知道我应该这样做:
foo(undefined, undefined, undefined, undefined, undefined, theFValue);
有没有更简洁的方法来做到这一点?
这样的:
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);
你可以使用
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});
这种方法没有前面例子中任何的缺点。
处理可选参数的更好方法是传递一个您查找其属性的对象:
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 });
跳过功能:
const skip = (num) => new Array(num);
跳过开始参数:
foo(...skip(4), f);
跳过结束参数:
foo(f, ...skip(4));
跳过中间参数:
foo(f, ...skip(4), f2);
如果你将传递一个属性名称为 f 的对象,那么你可以使用 destructuring assignment 和 ES6 语法,如下所示:
function foo({ f }) {
console.log(f);
}
foo({ g: 5, f: 10 });
如果这是你想要经常做的事情,那么考虑一个简单的包装器:
function bar(f) {
foo(undefined, undefined, undefined, undefined, undefined, f);
}
如果你只这样做一次,或者你想要随机排列参数,那么这种方法不是最好的。
我提供了一些可以帮助你实现的方法,如下所示,
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))
}
如果想让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))
}
对部分应用程序使用绑定:
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');
怎么样
function multiply(a = 2, b = 1) {
return a * b;
}
console.log(multiply(undefined, 3));
// expected output: 6
如果你传递一个未定义的参数,它将使用定义中的默认值。