Javascript 如何将对象属性排列到函数中的参数?

Javascript 如何将对象属性排列到函数中的参数?,javascript,typescript,Javascript,Typescript,假设我们有带参数的函数: function do(classId: number, schoolId: number, pupilId: number, teacherId: number, roomId: number) { } 我需要调用此函数传递对象,其属性应填充相应函数的参数,如: 案例一: let obj1 = {classId: 1, roomId: 3}; do(obj1); // passed only classId, roomId let obj2 = {school

假设我们有带参数的函数:

function do(classId: number, schoolId: number, pupilId: number, teacherId: number, roomId: number) {
}
我需要调用此函数传递对象,其属性应填充相应函数的参数,如:

案例一:

let obj1 = {classId: 1, roomId: 3}; 

do(obj1); // passed only classId, roomId
let obj2 = {schoolId: 5, pupilId: 4}; 

do(obj2); // passed only schoolId, pupilId
案例二:

let obj1 = {classId: 1, roomId: 3}; 

do(obj1); // passed only classId, roomId
let obj2 = {schoolId: 5, pupilId: 4}; 

do(obj2); // passed only schoolId, pupilId

如果我没记错的话,你想要这个:

const Do: (
    arg: {
        classId?: number;
        schoolId?: number;
        pupilId?: number;
        teacherId?: number;
        roomId?: number;
    }
) => any = ({ classId, schoolId, pupilId, teacherId, roomId }) => {};
我将参数列表替换为单个参数,即

注意,您不能使用
do
作为标识符名称,因此我将其更改为
do

另外,经典的JS函数对类型和typescript不是很友好,所以我用一个arrow函数重写了它


不确定是否有任何内置的功能,但下面的代码可能适合您

function doSome(classId, 
    schoolId, 
    pupilId, 
    teacherId, 
    roomId)
    {
        console.log(classId, 
    schoolId, 
    pupilId, 
    teacherId, 
    roomId)
    }

    const Do = obj => {
        var classId , schoolId , pupilId , teacherId , roomId
        for(var k in obj){
           eval(k + "=" + obj[k])
        }
        doSome(classId , schoolId , pupilId , teacherId , roomId)
    } 
更好的方法 首先,重构函数以采用Nurbol答案中的单个对象参数(我对此进行了投票),这是更好的解决方案。长参数的数字列表通常很难使用,而且容易出错

字面上的答案 也就是说,如果您真的想将对象键转换为现有函数的参数列表(例如说
do()
超出您的控制范围,无法重构),就像您的问题所述,您确实有一些选项

一种简单的方法是使用,它将对象的值转换为数组,数组可以是:

但是,不能保证值的顺序(这同样适用于所有对象键枚举,如
for..in
forEach()
),因此,如果函数参数的顺序很重要,这不是一个好主意,这在您的情况下显然很重要

为了保证正确的参数顺序,您需要以某种方式显式定义键的顺序。下面是一个通用函数的示例,该函数按顺序获取对象和键数组,然后使用
array.reduce()
生成有序参数列表数组:

function orderedArgs(obj: object, orderedKeys: string[]): any[] {
  return orderedKeys.reduce((args, key) => {
    args[orderedKeys.indexOf(key)] = obj[key as keyof object];
    return args;
  }, new Array(orderedKeys.length));
}

const argsOrder = ["classId", "schoolId", "pupilId", "teacherId", "roomId"];

const obj1 = { classId: 1, roomId: 3 }; 
doFn(...orderedArgs(obj1, argsOrder)); // passes: 1, undefined, undefined, undefined, 3

const obj2 = { schoolId: 5, pupilId: 4 };
doFn(...orderedArgs(obj2, argsOrder)); // passes: undefined, 5, 4, undefined, undefined
您可以使用帮助器函数进一步抽象这一点:

const callDo = (obj: object) => doFn(...orderedArgs(obj, ["classId", "schoolId", "pupilId", "teacherId", "roomId"]));

callDo({ classId: 1, roomId: 3 }); // passes: 1, undefined, undefined, undefined, 3

callDo({ schoolId: 5, pupilId: 4 }); // passes: undefined, 5, 4, undefined, undefined

我猜是把一个对象作为参数,还是我在监督什么?问题是对象键没有确定的顺序。在大多数情况下,它们可能按照它们在屏幕上显示的相同顺序列出,但这不能保证。顺序无关紧要,只需选择具有可选属性的对象,然后计算函数中设置的属性。没有理由使用orderSure,我可以传递任何属性集。如果您在问:如何使特定的
do()
函数接受对象而不是参数列表?或者您在问:如何使特定的
do()
函数接受对象或参数列表?或者你在问:给定一个接受参数列表的函数,我如何将它转换成另一个接受对象的函数?这是行不通的,因为参数不是可选的。@MuratKaragöz你能解释一下吗?没有“参数”,只有一个参数,这不是可选的,但我看不出有问题。Typescript会抱怨函数调用不符合所需的参数计数。您可以通过将
附加到参数来解决此问题。但是整个函数没有意义,因为您需要检查参数是否存在。总的来说,这个问题不是很好。你能在网上分享这个例子吗?@nurbolpysbayev你试着调用这个函数了吗?有点残酷,在那里循环评估我希望我有你拥有的时间(以及耐力和想象力)。我也对你的答案投了赞成票。