今天在做网页时突然碰到这样的JavaScript错误:
Uncaught RangeError: Maximum call stack size exceeded
百思不得其解,千次调试找不到原因。
表面上看,是因为递归次数太多导致内存被耗费太多,但是我的程序中,并没有一处使用递归算法啊。
最终冷静地思考了良久,终于发现,问题的根源在于网页中引用了两个不同的javascript库,而这两个库都对JavaScript原始对象的某些方法做了修改,从而导致出现了循环引用。具体说来,就是这么回事儿:
网页H引用了js库A和B,而A与B中对Math.pow方法都作了修改,如下图所示:
如果对Math.pow()方法的修改只进行一次,那么是不会有问题的:先用Math.power存储了Math.pow的原始版本,然后再用新的代码替换Math.pow。然而,在第二个库中,又执行到 Math.power = Math.pow时,那么Math.power就不再是保存Math.pow的原始版本了,因为Math.pow已经被第一个库改成了新代码,所以在Math.pow的新代码中调用Math.power()时,本意是调用原始版本,而实际上,却是调用自己了。于是造成了循环!
在进行替换前加一行判断代码,避免重复使用相同的方法名。
即
1
2
3
4
5
6
7
8
9
10
11
12
13
|
if
(Math.power ==
null
) {
// 此判断非常重要,如果Math.power 已经在别的地方定义过了,再次这样重新定义,会导致循环引用,从而引发
// Uncaught RangeError: Maximum call stack size exceeded 错误
Math.power = Math.pow;
Math.pow =
function
(x, y) {
if
(x != 0) {
return
Math.pow(x, y);
}
else
{
return
0;
}
}
}
// end if
|