取决于变量顺序的解构错误

问题描述 投票:0回答:2

我在反转链表时遇到了一些奇怪的解构行为这个问题

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let previous = null
    while (head) {

        // Version 1 - works
        [head.next, head, previous] = [previous, head.next, head]

        // Version 2 - doesn't work
        // [previous, head, head.next] = [head, head.next, previous]

        // Version 3 - doesn't work
        // [head, head.next, previous] = [head.next, previous, head]

    }
    return previous
};

我一辈子都弄不明白为什么破坏赋值 v2 和 v3 不起作用而版本 1 起作用。

head.next
分配导致了问题。错误是:

Line 16 in solution.js
        [previous, head, head.next] = [head, head.next, previous]
                              ^
TypeError: Cannot set properties of null (setting 'next')

有人可以解释版本 1 的工作方式而版本 2 和 3 不工作的方式吗?

javascript destructuring
2个回答
2
投票

JavaScript 正在一个一个地解构数组。版本 2 给你一个错误,因为 JavaScript 这样做:

// What you see:
[previous, head, head.next] = [head, head.next, previous]

// What the compiler sees:
previous = head;
head = head.next; // What is head.next? It hasn't been defined! throw TypeError
head.next = previous; // [JavaScript never gets here since there was an error]

因此只有第一个解决方案有效。


0
投票

如果将解构分解为单独的任务,则更容易看出差异。

版本 1 相当于:

let temp = [previous, head.next, head]
head.next = temp[0];
head = temp[1];
previous = temp[2];

版本 2 相当于:

let temp = [head, head.next, previous]
previous = temp[0];
head = temp[1];
head.next = temp[2];

和版本 3:

let temp = [head.next, previous, head]
head = temp[0];
head.next = temp[1];
previous = temp[2];

在第 2 版和第 3 版中,您在重新分配

head.next
之后分配 head = head.next
。但是您需要更改原始
next
节点的
head
属性,而不是新节点。

如果原来的

head.next
null
,赋值后尝试赋值
head.next
会报错,因为不能设置
null
的属性。

© www.soinside.com 2019 - 2024. All rights reserved.