是否有办法就地解构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抱怨它找不到名称a
,b
和c
:
someFunction({a, b, c} = obj);
答案 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。解。 如果您有任何问题,请给我评论。谢谢。