{"record":{"id":"54a10a9a7a0dfbf4","repo":"krahets/hello-algo","slug":"error","errorCode":null,"errorMessage":"索引越界","messagePattern":"索引越界","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"codes/javascript/chapter_array_and_linkedlist/my_list.js","lineNumber":32,"sourceCode":"    /* 构造方法 */\n    constructor() {\n        this.#arr = new Array(this.#capacity);\n    }\n\n    /* 获取列表长度（当前元素数量）*/\n    size() {\n        return this.#size;\n    }\n\n    /* 获取列表容量 */\n    capacity() {\n        return this.#capacity;\n    }\n\n    /* 访问元素 */\n    get(index) {\n        // 索引如果越界，则抛出异常，下同\n        if (index < 0 || index >= this.#size) throw new Error('索引越界');\n        return this.#arr[index];\n    }\n\n    /* 更新元素 */\n    set(index, num) {\n        if (index < 0 || index >= this.#size) throw new Error('索引越界');\n        this.#arr[index] = num;\n    }\n\n    /* 在尾部添加元素 */\n    add(num) {\n        // 如果长度等于容量，则需要扩容\n        if (this.#size === this.#capacity) {\n            this.extendCapacity();\n        }\n        // 将新元素添加到列表尾部\n        this.#arr[this.#size] = num;\n        this.#size++;","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/codes/javascript/chapter_array_and_linkedlist/my_list.js#L14-L50","documentation":"Thrown by the get(index) accessor of a hand-written dynamic-list (MyList) class when the requested index falls outside the populated range [0, size). This is a bounds guard on the backing array #arr; #capacity is the allocated length but only #size slots hold valid elements, so valid access stops at size-1. The check mirrors how Array.prototype / ArrayList style containers reject reads past their logical length.","triggerScenarios":"Calling list.get(-1), list.get(n) where n equals the current size (e.g. after pushing exactly n items), or calling get() on a freshly constructed list (size 0) with index 0. Any index >= list.size() or < 0 triggers it.","commonSituations":"Off-by-one loops (for (let i=0; i<=size; i++) then get(i)); reading an index that was valid before a remove() shrunk the list; assuming capacity() == size() and indexing up to capacity; iterating a list that was cleared without resetting the loop bound.","solutions":["Read list.size() first and constrain the index with i >= 0 && i < list.size() before calling get(i).","Fix the loop bound from i<=size to i<size.","Recompute the bound after any add/remove/insert that changes size; do not cache size across mutations.","Use the native Array or the list's toArray() when you only need sequential read access."],"exampleFix":"// before\nfor (let i = 0; i <= list.size(); i++) {\n  console.log(list.get(i)); // throws at i === size\n}\n// after\nfor (let i = 0; i < list.size(); i++) {\n  console.log(list.get(i));\n}","handlingStrategy":"validation","validationCode":"function safeGet(list, i) {\n  if (i >= 0 && i < list.size()) return list.get(i);\n  throw new RangeError(`index ${i} out of [0, ${list.size()})`);\n}","typeGuard":"function isValidIndex(list, i): i is number {\n  return typeof i === 'number' && Number.isInteger(i) && i >= 0 && i < list.size();\n}","tryCatchPattern":"try {\n  const v = list.get(i);\n} catch (e) {\n  if (e instanceof Error && e.message === '索引越界') {\n    // handle invalid index, e.g. return default or skip\n  } else throw e;\n}","preventionTips":["Always bound loops with i < list.size(), never i <= list.size().","Re-read list.size() after any add/insert/remove before indexing.","Wrap get() in a helper that returns a sentinel on out-of-range instead of throwing.","In tests, assert size() before accessing indices."],"tags":["data-structures","index-out-of-bounds","javascript","array"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}