如何检测何时访问JavaScript对象?我的意思是像范围对象,而不是全局对象或对象的属性。我希望能够执行以下操作:
"use strict"
!function() {
var o = {
onaccess: function() {
console.log("o was accessed");
}
}
var x = o; //"o was accessed" when this happens.
}();
答案 0 :(得分:0)
您不能通过这种方式访问您的对象,而不是访问该对象。
您可以尝试在“全局范围”中创建吸气剂(例如,在浏览器中也称为window
)或创建将吸气剂作为属性的对象,您可以将其视为“变量”在对象中”。
(function() {
var _x = {};
Object.defineProperty(window, 'x', {
get: function() {
alert("access");
return _x;
}
});
document.getElementById("g").addEventListener("click", function() {
var a = x;
});
document.getElementById("w").addEventListener("click", function() {
var a = window.x;
});
})();
<button id="g">Access global x</button>
<button id="w">Access window x</button>
该代码之所以有效,是因为当您访问变量(在这种情况下为x
)时,它将遍历上限作用域,直到找到包含该变量的作用域。最终它将在全局范围内寻找变量,即window
,在这里我设置了一个将在每次调用window.x
时运行的吸气剂(或简称为x
,它将最终在内部访问window.x
。
这很骇人,我不建议您这样做,因为您必须定义一个全局变量。但是,您可以尝试在某些属性中使用getter创建对象(与window.x
相同),因此不必使用全局范围,但必须始终通过以下方式访问对象属性:在对象之前:
(function() {
var _x = {};
var prop = {};
Object.defineProperty(prop, 'x', {
get: function() {
alert("access");
return _x;
}
});
document.getElementById("w").addEventListener("click", function() {
var a = prop.x;
});
})();
<button id="w">Access property x</button>
请注意,这仅适用于预定义的变量名称。如果您想捕获“所有”变量,则可以使用Proxies,它不可能在全局范围(窗口)上侵入,但可以与对象一起使用,例如:
var h = {
get: function(target, name){
alert("Accessed property " + name);
}
};
var p = new Proxy({}, h);
document.getElementById("x").addEventListener("click", function() {
var a = p.x;
});
document.getElementById("y").addEventListener("click", function() {
var a = p.y;
});
document.getElementById("r").addEventListener("click", function() {
var a = p[Math.random()];
});
<button id="x">Access x property</button>
<button id="y">Access y property</button>
<button id="r">Access random property</button>
答案 1 :(得分:0)
您可以创建一个代理,然后在每次调用函数时都可以记录一些内容,但是请注意,尽管在IE11或更低版本中代理不是100%可填充的
function realFunction() {
return {
a: "5"
}
}
var proxy = new Proxy(realFunction, {
get: function(target, key) {
const obj = target();
console.log("key", `'${key}'`, "was called on", target);
return obj[key];
}
});
proxy.a // "5"