InternalError: too much recursion
當函式呼叫過多,或函式缺少基本情況時,會發生 JavaScript 異常“遞迴過多”或“超出最大呼叫堆疊大小”。
訊息
RangeError: Maximum call stack size exceeded (Chrome) InternalError: too much recursion (Firefox) RangeError: Maximum call stack size exceeded. (Safari)
錯誤型別
Firefox 中的 InternalError;Chrome 和 Safari 中的 RangeError。
哪裡出錯了?
呼叫自身的函式稱為遞迴函式。一旦滿足條件,函式就會停止呼叫自身。這稱為基本情況。
在某些方面,遞迴類似於迴圈。兩者都多次執行相同的程式碼,並且都需要一個條件(以避免無限迴圈,或者在這種情況下是無限遞迴)。當函式呼叫過多,或函式缺少基本情況時,JavaScript 將丟擲此錯誤。
示例
根據退出條件,此遞迴函式執行 10 次。
js
function loop(x) {
if (x >= 10)
// "x >= 10" is the exit condition
return;
// do stuff
loop(x + 1); // the recursive call
}
loop(0);
將此條件設定為極高值將不起作用
js
function loop(x) {
if (x >= 1000000000000) return;
// do stuff
loop(x + 1);
}
loop(0);
// InternalError: too much recursion
此遞迴函式缺少基本情況。由於沒有退出條件,函式將無限期地呼叫自身。
js
function loop(x) {
// The base case is missing
loop(x + 1); // Recursive call
}
loop(0);
// InternalError: too much recursion
類錯誤:遞迴過多
js
class Person {
constructor() {}
set name(name) {
this.name = name; // Recursive call
}
}
const tony = new Person();
tony.name = "Tonisha"; // InternalError: too much recursion
當一個值被賦給屬性名 (this.name = name;) 時,JavaScript 需要設定該屬性。發生這種情況時,會觸發 setter 函式。
在此示例中,當 setter 被觸發時,它被告知再次執行相同的操作:設定它應該處理的同一屬性。這導致函式一次又一次地呼叫自身,使其無限遞迴。
如果 getter 中使用了相同的變數,也會出現此問題。
js
class Person {
get name() {
return this.name; // Recursive call
}
}
為避免此問題,請確保 setter 函式內部賦值的屬性與最初觸發 setter 的屬性不同。getter 也是如此。
js
class Person {
constructor() {}
set name(name) {
this._name = name;
}
get name() {
return this._name;
}
}
const tony = new Person();
tony.name = "Tonisha";
console.log(tony);