2.对象解构(ObjectAssignmentPattern)
const [first, second] = [1, 2];这段看似简单的代码背后,实际上涉及了复杂的操作。根据ECMAScript规范
CreateArrayLiteral [0], [0], #37 Star2 GetIterator r2, [1], [3] Star4 GetNamedProperty r4, [1], [5] Star3 LdaFalse Star5 LdaTheHole Star8 Mov <context>, r9 Ldar r5 JumpIfToBooleanTrue [33] (0x2b1a00040115 @ 57) LdaTrue Star5 CallProperty0 r3, r4, [11] Star10 JumpIfJSReceiver [7] (0x2b1a00040104 @ 40) CallRuntime [ThrowIteratorResultNotAnObject], r10-r10 GetNamedProperty r10, [2], [9] JumpIfToBooleanTrue [13] (0x2b1a00040115 @ 57) GetNamedProperty r10, [3], [7] Star10 LdaFalse Star5 Ldar r10 Jump [3] (0x2b1a00040116 @ 58) LdaUndefined Star0 Ldar r5 JumpIfToBooleanTrue [33] (0x2b1a0004013a @ 94) LdaTrue Star5 CallProperty0 r3, r4, [13] Star10 JumpIfJSReceiver [7] (0x2b1a00040129 @ 77) CallRuntime [ThrowIteratorResultNotAnObject], r10-r10 GetNamedProperty r10, [2], [9] JumpIfToBooleanTrue [13] (0x2b1a0004013a @ 94) GetNamedProperty r10, [3], [7] Star10 LdaFalse Star5 Ldar r10 Jump [3] (0x2b1a0004013b @ 95) LdaUndefined Star1 LdaSmi [-1] Star7 Star6 Jump [8] (0x2b1a00040148 @ 108) Star7 LdaZero Star6 LdaTheHole SetPendingMessage Star8 Ldar r5 JumpIfToBooleanTrue [35] (0x2b1a0004016d @ 145) Mov <context>, r11 GetNamedProperty r4, [4], [15] JumpIfUndefinedOrNull [26] (0x2b1a0004016d @ 145) Star12 CallProperty0 r12, r4, [17] JumpIfJSReceiver [19] (0x2b1a0004016d @ 145) Star13 CallRuntime [ThrowIteratorResultNotAnObject], r13-r13 Jump [11] (0x2b1a0004016d @ 145) Star11 LdaZero TestReferenceEqual r6 JumpIfTrue [5] (0x2b1a0004016d @ 145) Ldar r11 ReThrow LdaZero TestReferenceEqual r6 JumpIfFalse [8] (0x2b1a00040178 @ 156) Ldar r8 SetPendingMessage Ldar r7 ReThrow Ldar r1 Return我们可以看到数组解构涉及了大量的操作,包括创建迭代器、处理迭代结果等。这些额外的步骤可能会影响代码的执行效率。
const {0: first, 1: second} = [1, 2];
CreateArrayLiteral [0], [0], #37 Star2 LdaZero Star3 GetKeyedProperty r2, [1] Star0 LdaSmi [1] Star3 GetKeyedProperty r2, [3] Star1 Ldar r1 Return主要使用GetKeyedProperty指令直接获取属性值。
console.time('ArrayAssignmentPattern'); for (let i = 0; i < 100000; i++) { let [a, b] = [1, 2]; } console.timeEnd('ArrayAssignmentPattern'); // 堆代码 duidaima.com console.time('ObjectAssignmentPattern'); for (let i = 0; i < 100000; i++) { let {0: a, 1: b} = [1, 2]; } console.timeEnd('ObjectAssignmentPattern');
const arr = [1, 2]; const first = arr[0]; const second = arr[1];对于只需要少量元素的大型数组,可以结合使用对象解构和slice方法:
const bigArray = [1, 2, 3, 4, 5, /* ... 更多元素 */]; const {0: first, 1: second} = bigArray.slice(0, 2);在React等框架中使用props解构时,优先考虑对象解构:
// 优选 const {prop1, prop2} = props; // 避免 const [prop1, prop2] = Object.values(props);结语