{"record":{"id":"38c1aa374cb66749","repo":"krahets/hello-algo","slug":"the-deque-is-empty-38c1aa","errorCode":null,"errorMessage":"The Deque Is Empty.","messagePattern":"The Deque Is Empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/javascript/chapter_stack_and_queue/array_deque.js","lineNumber":88,"sourceCode":"    /* 佇列首出列 */\n    popFirst() {\n        const num = this.peekFirst();\n        // 佇列首指標向後移動一位\n        this.#front = this.index(this.#front + 1);\n        this.#queSize--;\n        return num;\n    }\n\n    /* 佇列尾出列 */\n    popLast() {\n        const num = this.peekLast();\n        this.#queSize--;\n        return num;\n    }\n\n    /* 訪問佇列首元素 */\n    peekFirst() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        return this.#nums[this.#front];\n    }\n\n    /* 訪問佇列尾元素 */\n    peekLast() {\n        if (this.isEmpty()) throw new Error('The Deque Is Empty.');\n        // 計算尾元素索引\n        const last = this.index(this.#front + this.#queSize - 1);\n        return this.#nums[last];\n    }\n\n    /* 返回陣列用於列印 */\n    toArray() {\n        // 僅轉換有效長度範圍內的串列元素\n        const res = [];\n        for (let i = 0, j = this.#front; i < this.#queSize; i++, j++) {\n            res[i] = this.#nums[this.index(j)];\n        }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/javascript/chapter_stack_and_queue/array_deque.js#L70-L106","documentation":"Thrown by ArrayDeque.peekFirst() (message: 'The Deque Is Empty.') when the deque has no elements. The method accesses nums[front]; without the guard it would return undefined, masking a logic error.","triggerScenarios":"Calling peekFirst() on a newly constructed or fully drained deque.","commonSituations":"Peeking before any push/unshift; underflow after a pop/poll loop; using the deque as a sliding window without checking remaining size.","solutions":["Call deque.isEmpty() (or check size > 0) before peekFirst().","Guard consumer loops with while (deque.size() > 0).","Return a default value or sentinel when the deque is empty instead of peeking."],"exampleFix":"// before\nconst head = deque.peekFirst(); // throws if empty\n\n// after\nconst head = deque.isEmpty() ? null : deque.peekFirst();","handlingStrategy":"validation","validationCode":"if (!deque.isEmpty()) {\n    const head = deque.peekFirst();\n}","typeGuard":null,"tryCatchPattern":"try {\n    const head = deque.peekFirst();\n} catch (e) {\n    if (e.message === 'The Deque Is Empty.') {\n        // deque is empty — return null or default\n    } else throw e;\n}","preventionTips":["Check isEmpty() before peekFirst().","Pair peek with the consuming pop/poll that runs only when size > 0.","Return a default value instead of peeking an empty deque."],"tags":["deque","javascript","empty-state","precondition"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}