Javascript - 捕获对象属性的访问权限

Ran*_*all 24 javascript object-properties

是否可以捕获对象的(任何)属性何时被访问或尝试访问?

例:

我创建了自定义对象 Foo

var Foo = (function(){
    var self = {};
    //... set a few properties
    return self;
})();
Run Code Online (Sandbox Code Playgroud)

然后有一些行动反对Foo- 有人试图访问财产bar

Foo.bar
Run Code Online (Sandbox Code Playgroud)

是否有方法(原型,也许)捕获这个?bar可能未定义Foo.我可以捕获任何尝试访问未定义属性的功能.

例如,如果bar未定义Foo,并且Foo.bar尝试了,例如:

Foo.prototype.undefined = function(){
    var name = this.name; //name of property they attempted to access (bar)
    Foo[name] = function(){
        //...do something
    };
    return Foo[name];
}
Run Code Online (Sandbox Code Playgroud)

但功能性,不像我的例子.

概念

Foo.* = function(){
}
Run Code Online (Sandbox Code Playgroud)

背景

如果我有自定义函数,每次调用此函数时都可以监听(见下文).只是想知道是否有可能获得财产.

Foo = function(){};
Foo.prototype.call = function(thisArg){
    console.log(this, thisArg);
    return this;
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 28

这可以在ECMAScript6中实现,并且现在可以在Firefox上使用新的代理服务器.在那之前,不,我担心没有办法挂钩.

我花了一段时间,但我终于找到了我之前对这个问题的回答.有关代理等的所有详细信息,请参阅该答案.

以下是该答案的代理示例:

const obj = new Proxy({}, {
    get: function(target, name, receiver) {
        if (!(name in target)) {
            console.log("Getting non-existant property '" + name + "'");
            return undefined;
        }
        return Reflect.get(target, name, receiver);
    },
    set: function(target, name, value, receiver) {
        if (!(name in target)) {
            console.log("Setting non-existant property '" + name + "', initial value: " + value);
        }
        return Reflect.set(target, name, value, receiver);
    }
});

console.log("[before] obj.foo = " + obj.foo);
obj.foo = "bar";
console.log("[after] obj.foo = " + obj.foo);
obj.foo = "baz";
console.log("[after] obj.foo = " + obj.foo);
Run Code Online (Sandbox Code Playgroud)

Live Copy (目前仅适用于Firefox) | 资源

运行时,输出:

"use strict";

const obj = new Proxy({}, {
    get: function(target, name, receiver) {
        if (!(name in target)) {
            console.log("Getting non-existant property '" + name + "'");
            return undefined;
        }
        return Reflect.get(target, name, receiver);
    },
    set: function(target, name, value, receiver) {
        if (!(name in target)) {
            console.log("Setting non-existant property '" + name + "', initial value: " + value);
        }
        return Reflect.set(target, name, value, receiver);
    }
});

console.log("[before] obj.foo = " + obj.foo);
obj.foo = "bar";
console.log("[after] obj.foo = " + obj.foo);
obj.foo = "baz";
console.log("[after] obj.foo = " + obj.foo);
Run Code Online (Sandbox Code Playgroud)

  • @RandyHall:可悲的是,没有.今天根本不可能拦截该操作(除了在Firefox上).这是为什么*代理被添加到下一版标准中.:-) (2认同)

Kat*_*314 5

我将在假设您正在尝试调试某些内容的情况下编写此内容。正如 Crowder 所说,这仅适用于较新的浏览器;因此它对于测试执行您不希望它执行的操作的代码非常有用。但是,我将其删除以用于生产代码。

Object.defineProperty(Foo, 'bar', {
  set: function() {
    debugger; // Here is where I'll take a look in the developer console, figure out what's
    // gone wrong, and then remove this whole block.
  }
});
Run Code Online (Sandbox Code Playgroud)

看起来 megavac 打败了我。您还可以在此处找到有关这些功能的一些 Mozilla 文档。