Search code examples
javascriptprototypal-inheritance

Method missing in JS


In python I can do something like this:

class Converter(object):
    def __init__(self, amount):
        self.amount = amount

    def rupy(self):
        return self.amount * 2

    def __getattr__(self, *args, **kwargs):
        if args[0] == 'rupies':
            return self.rupy

Is JS provide some way to achieve the same behavior? I googled a bit and found article about noSuchMethod but it works only in Firefox.

Edit: I don't wan't to have aliases I want to have a way to handle method missing generically


Solution

  • Short answer

    Does JavaScript have an equivalent to __getattr__?

    No :(


    Long answer

    It looks like you just want to map aliases, JavaScript has no problem with adding properties to things like this

    // set up
    function Converter(amount) {
        this.amount = amount;
    }
    Converter.prototype.rupy = function () {
        return this.amount * 2;
    };
    // add aliases
    var original = 'rupy', aliases = ['rupies'], i;
    for (i = 0; i < aliases.length; ++i)
        Converter.prototype[aliases[i]] = Converter.prototype[original];
    

    Now

    var foo = new Converter(1);
    foo.rupies(); // 2
    

    and have

    foo.rupies === foo.rupy; // true
    

    Future answer

    In ECMAScript 6 (Harmony) we have Proxies

    Constructor.prototype = Proxy(Constructor.prototype, {
        'get': function (target, name, child) {
                var o = child || target; /* =proxy? if proxy not inherited? */
                if (name in target) return o[name];
                if (name === 'rupies') return o['rupy'];
                return;
            },
        'set': function (target, name, val, child) {
                return target[name] = val;
            },
        'has': function (target, name) {
                return name in target; // do you want to make 'rupies' visible?
            },
        'enumerate': function (target) {
                for (var key in target) yield key;
            }
    });