观察已定义属性的值时超出了最大堆栈
Maximum stack exceeded when observing value of defined property
每当我尝试使用Object.observe
来观察我通过Object.defineProperty
定义属性的对象中的变化时,我都会得到Maximum call stack size exceeded
错误。
什么是正确的方法来绕过抛出这个错误,同时仍然能够使用这两个方法?
注意:Object.observe
仅适用于Chrome和Opera
var TestModule = (function () {
"use strict";
function TestClass() {
this.testValue = 0;
Object.defineProperty(this, "testValue", {
get: function () {
return this.testValue;
},
set: function (value) {
this.testValue = value;
},
enumerable: true,
configurable: false
});
}
return {
TestClass: TestClass
};
}());
<!DOCTYPE html>
<head>
<title>Stack Exceed Test</title>
<script src="../js/TestModule.js"></script>
</head>
<body>
<main>
<div id="logger" role="log"></div>
</main>
<script>
document.addEventListener("DOMContentLoaded", function () {
var logger = document.getElementById("logger"),
tc = new TestModule.TestClass();
function log(message) {
if (logger) {
logger.innerHTML = message;
} else {
console.error(message);
}
}
if (typeof Object.observe === "function") {
Object.observe(tc, function (changes) {
console.log("Change");
});
try {
tc.testValue = 5;
} catch (e) {
log(e);
}
} else {
log("Object.observe is unsupported in your browser");
}
});
</script>
</body>
在Object.defineProperty...
中反复读写同一个变量
您应该在TestClass的第一行更改this.testValue
的名称。我建议将其重命名为this._testValue
,这是一种命名变量以指示它们是"私有"的约定。
注意,您也可以保留this.testValue
并完全删除Object.defineProperty...
部分,因为您所做的只是读写值,这是默认值。
var TestModule = (function () {
"use strict";
function TestClass() {
this._testValue = 0;
Object.defineProperty(this, "testValue", {
get: function () {
return this._testValue;
},
set: function (value) {
this._testValue = value;
},
enumerable: true,
configurable: false
});
}
return {
TestClass: TestClass
};
}());
<!DOCTYPE html>
<head>
<title>Stack Exceed Test</title>
<script src="../js/TestModule.js"></script>
</head>
<body>
<main>
<div id="logger" role="log"></div>
</main>
<script>
document.addEventListener("DOMContentLoaded", function () {
var logger = document.getElementById("logger"),
tc = new TestModule.TestClass();
function log(message) {
if (logger) {
logger.innerHTML = message;
} else {
console.error(message);
}
}
if (typeof Object.observe === "function") {
Object.observe(tc, function (changes) {
console.log("Change");
});
try {
tc.testValue = 5;
} catch (e) {
log(e);
}
} else {
log("Object.observe is unsupported in your browser");
}
});
</script>
</body>
另一种解决这个问题的方法,如果你不想用间接的方式"包装"你的值,是使用Object.getNotifier()
,它允许你手动发出通知,并保留一个不是你的对象成员的局部变量。
如果你使用通知器,你可以绕过必须有对象属性,实际上不会使用。如果您使用包装方法,您将在对象上同时拥有_testValue
和 testValue
。使用通知器,您将只有有testValue
。
考虑代码更改:
function TestClass() {
var testValue, notifier;
/*
* The new locally scoped varible which will
* be captured by the getter/setter closure
*/
testValue = 0;
/*
* Create a notifier for the object
* which we can use to trigger
* Object.observe events manually
*/
notifier = Object.getNotifier(this);
Object.defineProperty(this, "testValue", {
get: function () {
return testValue;
},
set: function (value) {
/*
* Use the notifier to trigger
* the observe()
*/
notifier.notify({
type: "update",
name: "testValue",
oldValue: testValue
});
testValue = value;
},
enumerable: true,
configurable: false
});
}
相关文章:
- Rails File_field最大堆栈大小
- 是什么让一个“;Uncaught RangeError:超过了最大调用堆栈大小“;错误(Chrome,在其他浏览器中显示
- 超过了async.detect最大调用堆栈大小
- 如何制作大的自定义社交媒体按钮
- 超过了最大调用堆栈大小,循环无限
- 超过了最大调用堆栈大小.递归标签
- 日志:未捕获的范围错误:超过了最大调用堆栈大小
- 是否排除节点中错误堆栈的第一行?/节点中的自定义错误类型
- 未捕获的范围错误:setTimeout()超过了最大调用堆栈大小
- JavaScript继承:未捕获的范围错误:超过了最大调用堆栈大小
- 通过套接字发送画布元素,JS中的最大堆栈大小
- 递归 - 测试最大堆栈大小时,调用堆栈无法弹出
- 已达到最大堆栈大小
- 超过了最大堆栈大小
- 观察已定义属性的值时超出了最大堆栈
- 自定义缩放控制导致最大调用堆栈大小超出错误
- Javascript错误?每行匿名函数的最大堆栈
- "超过最大堆栈大小“;当使用“;这个.超级“;聚合物层次结构
- 如何在node.js中设置最大堆栈大小
- 谷歌地图API自定义地图类型允许边界的最大调用堆栈大小超过/太多递归