Is There an Equivalent of the _Nosuchmethod_ Feature for Properties, or a Way to Implement It in Js

Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?

UPDATE: ECMAScript 6 Proxies are widely supported now. Basically, if you don't need to support IE11, you can use them.

Proxy objects allow you to define custom behavior for fundamental operations, like property lookup, assignment, enumeration, function invocation, etc.

Emulating __noSuchMethod__ with ES6 Proxies

By implementing traps on property access, you can emulate the behavior of the non-standard __noSuchMethod__ trap:

function enableNoSuchMethod(obj) {
return new Proxy(obj, {
get(target, p) {
if (p in target) {
return target[p];
} else if (typeof target.__noSuchMethod__ == "function") {
return function(...args) {
return target.__noSuchMethod__.call(target, p, args);
};
}
}
});
}

// Example usage:

function Dummy() {
this.ownProp1 = "value1";
return enableNoSuchMethod(this);
}

Dummy.prototype.test = function() {
console.log("Test called");
};

Dummy.prototype.__noSuchMethod__ = function(name, args) {
console.log(`No such method ${name} called with ${args}`);
return;
};

var instance = new Dummy();
console.log(instance.ownProp1);
instance.test();
instance.someName(1, 2);
instance.xyz(3, 4);
instance.doesNotExist("a", "b");

Does JavaScript have the equivalent of Python's __getattribute__?

It is not possible for properties, though there is a non-standard way (__noSuchMethod__) for methods which is only available for Firefox.

Javascript: Object with a single handler for all method calls

Yes, it is possible with an ES6 Proxy on an empty object:

var Algebra = new Proxy({}, {    // Intercept member access:    get: function(target, name) {        // Helper function to translate word to number        // -- extend it to cover for more words:        function toNumber(name) {            var pos = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"].indexOf(name);            return pos === -1 ? NaN : pos;        }        // See if we can understand the name:        var parts = name.split('plus');        if (parts.length > 1) {            parts = parts.map(toNumber);            // Return result as a function:            return _ => parts[0] + parts[1];        }        var parts = name.split('times');        if (parts.length > 1) {            parts = parts.map(toNumber);            // Return result as a function:            return _ => parts[0] * parts[1];        }    }});
// Sample calls:console.log(Algebra.twoplustwo());console.log(Algebra.fourtimesnine());

Is there Object.watch for all properties / a shim for __noSuchMethod__ available?

Nope, at least, not for Chrome. __noSuchMethod__ only works for functions, anyway.

Proxy support is under discussion for the next version of ECMAScript (Harmony), and even already implemented in SpiderMonkey. Until then, you're out of luck, I'm afraid.

— there was a request to implement __noSuchMethod__ in V8 but it was refused. Requests to implement Proxy haven't been any more successful: 633 was merged as duplicate, and the Chromium team doesn't care much about implementing Proxy support.

doesNotUnderstand for JavaScript?

There is no catch-all method defined in the JavaScript standard, but Mozilla implements the non-standard __noSuchMethod__ for SpiderMonkey and Rhino (including Firefox obviously).

You may also be interested in checking out @CMS' answer given to the following Stack Overflow question:

  • Is there an equivalent of the noSuchMethod feature for properties, or a way to implement it in JS?

JavaScript getter for all properties

Proxy can do it! I'm so happy this exists!! An answer is given here: Is there a javascript equivalent of python's __getattr__ method? . To rephrase in my own words:

var x = new Proxy({}, {  get(target, name) {    return "Its hilarious you think I have " + name  }})
console.log(x.hair) // logs: "Its hilarious you think I have hair"

javascript: implement something like python's __getattribute__?

As pointed out by @thg435 the issue was discussed in a narrower scope at Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS? but the answer from there applies here.

An appropriate API for doing this in javascript is in the making, called ECMAScript Harmony Proxies which may have been replaced recently with Direct Proxy. This API is not yet supported cross-platform, but it may work for some platform, such as recent firefox and chrome.



Related Topics



Leave a reply



Submit