每当我尝试使用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>
答案 0 :(得分:1)
您正在Object.defineProperty...
您应该在TestClass的第一行更改this.testValue
的名称。我建议将其重命名为this._testValue
,这是一个命名变量的约定,以指示它们是&#34;私有&#34;。
注意,您也可以保留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
};
}());
&#13;
<!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>
&#13;
答案 1 :(得分:0)
解决这个问题的另一种方法,如果你不想排序&#34;包装&#34;你的间接价值是使用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
});
}