Skip to content Skip to sidebar Skip to footer

Modifying An Object's Prototype To Made A Log To The Console Every Time A Variable Is Requested

I'm sure I've seen this before somewhere. I'm just beginning looking at prototypes so I don't know much. What's the correct prototype declaration so it catches all requests for var

Solution 1:

You could make x a method (instead of a property), override it in the subclass (adding your logging call) and then use prototype.x.call to call the super method.

varFoo = function () {
    this.x = function () {
        console.log('ancestor x');
    }
}

varBar = function () {
    this.x = function () {
        console.log('inherited x');
        Bar.prototype.x.call(this);
    }
}

Bar.prototype = newFoo;

newBar().x();

Otherwise, there are some vendor extensions and ES5/6 getter methods, but you'll have to contend with erratic browser support for either of those options.

Fiddle

Solution 2:

You are looking for getters/setters:

foo = {};
var x;
Object.defineProperty(foo, 'x', {
    get: function () {
        console.log("Getting:",x);
        return x; // or not..
    },
    set: function (val) {
        console.log("Setting to:", val);
        x = val;
        return x;
    }
});

Of course, these don't work on legacy browser.

Edit: I've created the Waject for this sort of thing: https://github.com/s-p-n/Waject

Solution 3:

What's the correct prototype declaration so it catches all requests for varibles? With myObject being an object with the altered prototype.

That's not really related to JavaScript's prototypical inheritance. Creating objects with prototypes can either be done by using the new keyword on constructor functions with their prototype property, or via Object.create. What you're interested in is how to construct an object where every property access…

would get caught by the function

This unfortunately not possible with current JavaScript. You can only set up properties (with values, or with getters/setters) with specific names, a catch-all behaviour is currently not implemented - though some few engines support the Proxy draft. For that, see Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?, Javascript array with default values (equivalent of Python's defaultdict)? or Set undefined javascript property before read.


I think this comes closest to what you want - using an explicit getter function instead of properties:

function Entity() {
   this.data = {position_X:5, foo:"bar", …};
}
Entity.prototype.get = function (name) {
    console.log("access on "+name);
    returnthis.data[name];
};

var entity = new Entity;
entity.get("x"); // undefined, but logs "access on x"
entity.get("position_X"); // 5, and logs "access on position_X"
entity.get("foo"); // "bar", and logs "access on foo"

Post a Comment for "Modifying An Object's Prototype To Made A Log To The Console Every Time A Variable Is Requested"