ค้นหาเว็บไซต์

javascript - วิธีจัดเรียงคุณสมบัติของอ็อบเจ็กต์เป็นพารามิเตอร์ในฟังก์ชัน?


สมมติว่าเรามีฟังก์ชันที่มีพารามิเตอร์:

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

คำตอบ #1

ถ้าฉันเข้าใจคุณถูกต้อง คุณต้องการแบบนี้:

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

ฉันได้แทนที่รายการของพารามิเตอร์ด้วยพารามิเตอร์เดียว ซึ่งเป็นรูปแบบการทำลายวัตถุ

โปรดทราบว่าคุณไม่สามารถใช้ do เป็นชื่อผู้ระบุได้ ดังนั้นฉันจึงเปลี่ยนเป็น Do.

ฟังก์ชัน JS แบบคลาสสิกก็ไม่ค่อยเป็นมิตรกับชนิดข้อมูลและ TypeScript ดังนั้นฉันจึงเขียนใหม่โดยใช้ฟังก์ชันลูกศร

สนามเด็กเล่น

คำตอบ #2

วิธีที่ดีกว่า

ก่อนอื่น การปรับโค้ดฟังก์ชันให้รับพารามิเตอร์เป็นอ็อบเจ็กต์เดียวเหมือนในคำตอบของ Nurbol (ซึ่งผมให้คะแนนขึ้น) ตามความคิดเห็นของผมเป็นวิธีแก้ไขที่ดีกว่า รายการอาร์กิวเมนต์ยาวๆ ของตัวเลขมักจะใช้งานยากและมีแนวโน้มที่จะเกิดข้อผิดพลาด

คำตอบตามตัวอักษร

อย่างไรก็ตาม หากคุณต้องการแปลงคีย์ของออบเจ็กต์เป็นรายการอาร์กิวเมนต์สำหรับฟังก์ชันที่มีอยู่จริงๆ (ตัวอย่างเช่น สมมติว่า do() อยู่นอกการควบคุมของคุณและไม่สามารถปรับโครงสร้างใหม่ได้) ตามที่คำถามของคุณระบุ คุณยังมีตัวเลือกบางอย่าง

วิธีการที่ง่ายและตรงไปตรงมาคือการใช้ Object.values() ซึ่งจะทำการแปลงค่าของอ็อบเจ็กต์ให้เป็นอาร์เรย์ที่สามารถกระจายเป็นอาร์กิวเมนต์ของฟังก์ชันได้:

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

อย่างไรก็ตาม ลำดับของค่าจะไม่ได้รับประกัน (สิ่งเดียวกันนี้ใช้กับการวนซ้ำคีย์ของออบเจกต์ทั้งหมด เช่น 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

บทความที่เกี่ยวข้อง