Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to catch an attempt to access a non existant property or method?

Tags:

javascript

For instance this code:

function stuff() {
  this.onlyMethod = function () {
    return something;
  }
}

// some error is thrown
stuff().nonExistant();

Is there a way to do something like PHP's __call as a fallback from inside the object?

function stuff() {
  this.onlyMethod = function () {
    return something;
  }
  // "catcher" function
  this.__call__ = function (name, params) {
    alert(name + " can't be called.");
  }
}

// would then raise the alert "nonExistant can't be called".
stuff().nonExistant();

Maybe I'll explain a bit more what I'm doing.

The object contains another object, which has methods that should be accessible directly through this object. But those methods are different for each object, so I can't just route them, i need to be able to call them dynamically.

I know I could just make the object inside it a property of the main object stuff.obj.existant(), but I'm just wondering if I could avoid it, since the main object is sort of a wrapper that just adds some functionality temporarily (and makes it easier to access the object at the same time).

like image 550
Tor Valamo Avatar asked Apr 19 '10 10:04

Tor Valamo


People also ask

How do you find out if a property is undefined?

In a JavaScript program, the correct way to check if an object property is undefined is to use the typeof operator. If the value is not defined, typeof returns the 'undefined' string.

Why is an object undefined?

undefined means that the variable value has not been defined; it is not known what the value is. null means that the variable value is defined and set to null (has no value).


1 Answers

Well, it seems that with harmony (ES6), there will be a way, and it's more complicated compared to the way other programing languages do it. Basically, it involves using the Proxy built-in object to create a wrapper on the object, and modify the way default behavior its implemented on it:

obj  = new Proxy({}, 
        { get : function(target, prop) 
            { 
                if(target[prop] === undefined) 
                    return function()  {
                        console.log('an otherwise undefined function!!');
                    };
                else 
                    return target[prop];
            }
        });
obj.f()        ///'an otherwise undefined function!!'
obj.l = function() {console.log(45);};
obj.l();       ///45

The Proxy will forward all methods not handled by handlers into the normal object. So it will be like if it wasn't there, and from proxy you can modify the target. There are also more handlers, even some to modify the prototype getting, and setters for any property access yes!.

As you would imagine, this isn't supported in all browsers right now, but in Firefox you can play with the Proxy interface quite easy, just go to the MDN docs

It would make me happier if the managed to add some syntactic sugar on this, but anyway, its nice to have this kind of power in an already powerful language. Have a nice day! :)

PD: I didn't copy rosettacode js entry, I updated it.

like image 119
Nicolas NZ Avatar answered Oct 08 '22 20:10

Nicolas NZ