Answers:
这意味着在代码的某处,您正在调用一个函数,该函数又调用另一个函数,依此类推,直到达到调用堆栈限制。
这几乎总是因为没有满足基本情况的递归函数。
考虑这段代码...
(function a() {
a();
})();
这是经过几次调用后的堆栈...
如您所见,调用堆栈会不断增长,直到达到极限:浏览器采用硬编码的堆栈大小或内存耗尽。
为了对其进行修复,请确保您的递归函数具有可以满足的基本情况。
(function a(x) {
// The following condition
// is the base case.
if ( ! x) {
return;
}
a(--x);
})(10);
如果您不小心两次导入/嵌入相同的JavaScript文件,有时可以得到此文件,值得在检查器的“资源”选项卡中进行检查。
就我而言,我正在发送输入元素而不是它们的值:
$.post( '',{ registerName: $('#registerName') } )
代替:
$.post( '',{ registerName: $('#registerName').val() } )
这使我的Chrome标签冻结,直到页面无响应时甚至没有显示“等待/杀死”对话框。
代码中的某个地方有一个递归循环(即,一个函数最终会一次又一次地调用自身,直到堆栈已满)。
其他浏览器要么堆栈更大(因此您会超时),要么由于某种原因(可能是错误放置的try-catch)吞没了错误。
错误发生时,使用调试器检查调用堆栈。
检测stackoverflows的问题是有时堆栈跟踪会消失,您将无法看到实际情况。
我发现一些Chrome较新的调试工具对此有用。
点击Performance tab
,确保Javascript samples
已启用,您将获得类似的信息。
很明显这里有溢出!如果单击,extendObject
您将可以在代码中实际看到确切的行号。
您还可以看到可能会有所帮助的时机,也可能会看到红鲱鱼。
如果您实际上找不到问题,另一个有用的技巧是console.log
在您认为问题所在的地方放置很多语句。上面的上一步可以帮助您。
在Chrome中,如果您重复输出相同的数据,它将像这样显示,以更清楚地指出问题所在。在这种情况下,堆栈在最终崩溃之前命中了7152帧:
就我而言,我正在使用以下命令将大字节数组转换为字符串:
String.fromCharCode.apply(null, new Uint16Array(bytes))
bytes
包含数百万个条目,太大而无法容纳在堆栈中。
var uintArray = new Uint16Array(bytes); var converted = []; uintArray.forEach(function(byte) {converted.push(String.fromCharCode(byte))});
就我而言,点击事件正在子元素上传播。因此,我不得不提出以下几点:
e.stopPropagation()
点击事件:
$(document).on("click", ".remove-discount-button", function (e) {
e.stopPropagation();
//some code
});
$(document).on("click", ".current-code", function () {
$('.remove-discount-button').trigger("click");
});
这是html代码:
<div class="current-code">
<input type="submit" name="removediscountcouponcode" value="
title="Remove" class="remove-discount-button">
</div>
如果出于某种原因需要无限的进程/递归运行,则可以在单独的线程中使用Webworker。 http://www.html5rocks.com/zh-CN/tutorials/workers/basics/
如果要操纵dom元素并重绘,请使用动画 http://creativejs.com/resources/requestanimationframe/
几乎每个答案都指出,这只能由无限循环引起。事实并非如此,否则您可能会通过深度嵌套的调用来使堆栈超负荷运行(并不是说这很有效,但这肯定在可能的范围内)。如果您可以控制JavaScript VM,则可以调整堆栈大小。例如:
node --stack-size=2000
以我为例,两个jQuery模态相互重叠显示。防止这种情况解决了我的问题。
我们最近在我们正在处理的管理网站中添加了一个字段-contact_type ...容易吗?好吧,如果您调用选择的“类型”并尝试通过jquery ajax调用发送该消息,它将失败,并且此错误会深深地藏在jquery.js中。不要这样做:
$.ajax({
dataType: "json",
type: "POST",
url: "/some_function.php",
data: { contact_uid:contact_uid, type:type }
});
问题是type:type-我相信是我们将参数命名为“ type”-拥有一个名为type的值变量不是问题。我们将其更改为:
$.ajax({
dataType: "json",
type: "POST",
url: "/some_function.php",
data: { contact_uid:contact_uid, contact_type:type }
});
并相应地重写some_function.php-问题已解决。
这也会导致Maximum call stack size exceeded
错误:
var items = [];
[].push.apply(items, new Array(1000000)); //Bad
同样在这里:
items.push(...new Array(1000000)); //Bad
但要注意:以这种方式使用应用时,存在冒超出JavaScript引擎参数长度限制的风险。应用带有过多参数(想想成千上万个参数)的函数的结果因引擎而异(JavaScriptCore的硬编码参数限制为65536),因为该限制(甚至包括任何过大堆栈的性质)行为)未指定。一些引擎将引发异常。更为有害的是,其他人将任意限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际上的限制当然要高得多),则好像在上面的示例中通过了参数5、6、2、3一样,而不是整个数组。
因此,请尝试:
var items = [];
var newItems = new Array(1000000);
for(var i = 0; i < newItems.length; i++){
items.push(newItems[i]);
}
下面的相同代码的两个调用如果减少1,则在我的计算机上的Chrome 32中均可运行,例如17905与17904。如果按原样运行,它们将产生错误“ RangeError:超出最大调用堆栈大小”。似乎此限制不是硬编码的,而是取决于计算机的硬件。看起来,如果作为函数调用,则此自我施加的限制要高于作为方法调用时的约束,即,当作为函数调用时,此特定代码使用的内存更少。
作为方法调用:
var ninja = {
chirp: function(n) {
return n > 1 ? ninja.chirp(n-1) + "-chirp" : "chirp";
}
};
ninja.chirp(17905);
作为功能调用:
function chirp(n) {
return n > 1 ? chirp( n - 1 ) + "-chirp" : "chirp";
}
chirp(20889);
您可以在crome浏览器中找到递归函数,按ctrl + shift + j,然后按Source选项卡,这将为您提供代码编译流程,并且您可以在代码中使用断点来查找。
我还面临类似的问题,这是使用下拉徽标上传框上传徽标时的详细信息
<div>
<div class="uploader greyLogoBox" id="uploader" flex="64" onclick="$('#filePhoto').click()">
<img id="imageBox" src="{{ $ctrl.companyLogoUrl }}" alt=""/>
<input type="file" name="userprofile_picture" id="filePhoto" ngf-select="$ctrl.createUploadLogoRequest()"/>
<md-icon ng-if="!$ctrl.isLogoPresent" class="upload-icon" md-font-set="material-icons">cloud_upload</md-icon>
<div ng-if="!$ctrl.isLogoPresent" class="text">Drag and drop a file here, or click to upload</div>
</div>
<script type="text/javascript">
var imageLoader = document.getElementById('filePhoto');
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
$('.uploader img').attr('src',event.target.result);
}
reader.readAsDataURL(e.target.files[0]);
}
</script>
</div>
CSS.css
.uploader {
position:relative;
overflow:hidden;
height:100px;
max-width: 75%;
margin: auto;
text-align: center;
img{
max-width: 464px;
max-height: 100px;
z-index:1;
border:none;
}
.drag-drop-zone {
background: rgba(0, 0, 0, 0.04);
border: 1px solid rgba(0, 0, 0, 0.12);
padding: 32px;
}
}
.uploader img{
max-width: 464px;
max-height: 100px;
z-index:1;
border:none;
}
.greyLogoBox {
width: 100%;
background: #EBEBEB;
border: 1px solid #D7D7D7;
text-align: center;
height: 100px;
padding-top: 22px;
box-sizing: border-box;
}
#filePhoto{
position:absolute;
width:464px;
height:100px;
left:0;
top:0;
z-index:2;
opacity:0;
cursor:pointer;
}
在更正之前,我的代码是:
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
onclick="$('#filePhoto').click()"
$('.uploader img').attr('src',event.target.result);
}
reader.readAsDataURL(e.target.files[0]);
}
控制台中的错误:
我通过onclick="$('#filePhoto').click()"
从div标签中删除解决了它。
我遇到了同样的问题,我通过删除一个在ajax上使用过两次的字段名来解决了该问题,例如
jQuery.ajax({
url : '/search-result',
data : {
searchField : searchField,
searchFieldValue : searchField,
nid : nid,
indexName : indexName,
indexType : indexType
},
.....
我知道此线程很旧,但是我认为值得一提的是我发现此问题的情况,因此它可以帮助其他人。
假设您有这样的嵌套元素:
<a href="#" id="profile-avatar-picker">
<span class="fa fa-camera fa-2x"></span>
<input id="avatar-file" name="avatar-file" type="file" style="display: none;" />
</a>
您无法在其父级事件内操纵子级元素事件,因为它会传播给自身,从而进行递归调用,直到引发异常为止。
因此此代码将失败:
$('#profile-avatar-picker').on('click', (e) => {
e.preventDefault();
$('#profilePictureFile').trigger("click");
});
您有两种选择可以避免这种情况:
如果您使用的是Google地图,请检查所传递的经纬度是否new google.maps.LatLng
格式正确。就我而言,它们是作为未定义的传递的。
在我的情况下的问题是因为我的子级路由与父级路径相同:
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [
{ path: '', redirectTo: 'home', pathMatch: 'prefix' },
{ path: 'home', loadChildren: './home.module#HomeModule' },
]
}
];
所以我不得不删除孩子路线的线
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [
{ path: 'home', loadChildren: './home.module#HomeModule' },
]
}
];
就我而言,我在ajax调用中遇到此错误,并且尝试传递该变量的数据尚未定义,这向我显示了此错误,但未描述未定义的变量。我添加了定义,变量n获得了价值。
以我为例,我错误地分配了相同的变量名,并将其分配给val函数“ class_routine_id”
var class_routine_id = $("#class_routine_id").val(class_routine_id);
它应该像:
var class_routine_id = $("#class_routine_id").val();
在Angular中,如果您使用的是mat-select并且有400多个选项,则可能会发生此错误 https://github.com/angular/components/issues/12504
您必须更新@ angular / material版本
data
ajax 发送变量(未声明它们)时遇到此错误。通过声明变量修复了错误。