如何将对象属性布置为函数中的参数?

时间:2018-11-30 14:30:51

标签: 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 = {schoolId: 5, pupilId: 4}; 

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

3 个答案:

答案 0 :(得分:5)

如果我正确地找到了您,则需要这样:

const Do: (
    arg: {
        classId?: number;
        schoolId?: number;
        pupilId?: number;
        teacherId?: number;
        roomId?: number;
    }
) => any = ({ classId, schoolId, pupilId, teacherId, roomId }) => {};

我将参数列表替换为单个参数,即object destructuring pattern

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

经典的JS函数对类型和打字稿也不是很友好,因此我使用箭头函数重写了它。

The playground

答案 1 :(得分:2)

更好的方法

首先,将函数重构为采用Nurbol的答案(我赞成)中的单个对象参数是IMO更好的解决方案。长的数字参数列表通常很难使用并且容易出错。

字面意思

也就是说,如果您真的想将对象键的值转换为现有函数的参数列表(例如说do()超出了您的控制范围,无法重构),例如您的问题状态,那么您确实有一些选择

一种简单的方法是使用Object.values(),它将对象的值转换为可以是spread in as function arguments的数组:

do(...Object.values(obj));

但是,不能保证值的顺序(所有对象键枚举都适用,例如for..inforEach()),所以如果函数的顺序不是一个好主意论点很重要,在您的情况下很明显。

要确保正确的参数顺序,您需要以某种方式明确定义键的顺序。这是一个通用函数的示例,该函数按顺序接收对象和键数组,然后使用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

答案 2 :(得分:0)

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

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)
    }