函数调用的对象分解

时间:2019-04-21 03:13:30

标签: javascript typescript function object ecmascript-6

是否有办法就地解构JS对象,而不是将解构后的变量分配给作用域?

代替这样做:

const { a, b, c } = obj;
someFunction(a, b, c);

我想这样做:

someFunction({a, b, c} from obj);

或功能上等效的东西。

在有以下两个规定的情况下,我想这样做:

  • 我不想将变量名放入封闭范围。

  • 我不想传递整个对象obj,因此使散布运算符成为一种选择。

我唯一剩下的选择就是使用

someFunction(obj.a, obj.b, obj.c);

在这种情况下哪个很好,但是当obj却是一个长标识符时,可能会降低可读性。

像这样可能吗?我尝试在表达式中使用赋值作为一种解决方法,但我的IDE抱怨它找不到名称abc

someFunction({a, b, c} = obj);

5 个答案:

答案 0 :(得分:6)

一种选择是使用.map提取所需的每个属性的值,并将其分布到参数列表中:

someFunction(
  ...['a', 'b', 'c'].map(prop => obj[prop])
);

不幸的是,解构需要您不需要的中间变量的创建。

答案 1 :(得分:3)

IIFE应该起作用:

((({ a, b, c }) => someFunction(a, b, c))(obj);

答案 2 :(得分:1)

这是我要怎么做:

function foo( { x, y } ) {
	console.log( x, y );
}

foo( { y: 1, x: 2 } );	 // 2 1


对于OP的特定请求,即不传递整个对象(或在全局范围内声明变量)。将对象分解为块范围变量将是恕我直言的最佳方法。

const obj = { x: 1, y: 2 }

function foo( x, y ) {
    console.log( x, y );
}

{   let { x, y } = obj;
    foo( x, y );   // 1 2
}

console.log(x) // "ReferenceError: x is not defined

答案 3 :(得分:0)

当对象的属性顺序与前 N 个参数对齐时,您可以使用:

someFunction(...Object.values(obj))

答案 4 :(得分:-1)

对象分解中的函数调用参数未知

当您无法访问或更改函数声明,或者只是不想这么做时,这是必需的。

const getParamNames = func => {
    const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
    const ARGUMENT_NAMES = /([^\s,]+)/g;
    let fnStr = func.toString().replace(STRIP_COMMENTS, '');
    let result = fnStr.slice(fnStr.indexOf('(')+1, 
    fnStr.indexOf(')')).match(ARGUMENT_NAMES);
    if (result === null) result = [];
    return result;
}

const callFunctionFromObject = (func, obj) => {
    let params = getParamNames2(func)
    return func(...params.map(prop => obj[prop]))
}

用法示例:

//Function declared somewhere:
var logForStackOverflow = (a, b, c) => console.log(a, b, c)

//ex1
callFunctionFromObject(logForStackOverflow, {a: 1});
1 undefined undefined
//ex2
callFunctionFromObject(logForStackOverflow, {b: 1})
undefined 1 undefined
//ex3
callFunctionFromObject(logForStackOverflow, {b: "hello", c:3, a:[1, 2, 3]})
[1, 2, 3] "hello" 3

感谢@CertainPerformance。解。 如果您有任何问题,请给我评论。谢谢。