Is There A Way To Catch An Attempt To Access A Non Existant Property Or Method?
Solution 1:
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 = newProxy({},
{ get : function(target, prop)
{
if(target[prop] === undefined)
returnfunction() {
console.log('an otherwise undefined function!!');
};
elsereturn 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.
Solution 2:
There is a way to define a generic handler for calls on non-existant methods, but it is non-standard. Checkout the noSuchMethod for Firefox. Will let you route calls to undefined methods dynamically. Seems like v8 is also getting support for it.
To use it, define this method on any object:
var a = {};
a.__noSuchMethod__ = function(name, args) {
console.log("method %s does not exist", name);
};
a.doSomething(); // logs "method doSomething does not exist"
However, if you want a cross-browser method, then simple try-catch blocks if the way to go:
try {
a.doSomething();
}
catch(e) {
// do something
}
If you don't want to write try-catch throughout the code, then you could add a wrapper to the main object through which all function calls are routed.
functionmain() {
this.call = function(name, args) {
if(this[name] && typeofthis[name] == 'function') {
this[name].call(args);
}
else {
// handle non-existant method
}
},
this.a = function() {
alert("a");
}
}
var object = newmain();
object.call('a') // alerts "a"
object.call('garbage') // goes into error-handling code
Solution 3:
It seems that you know your way around JS. Unfortunately, I don't know of such feature in the language, and am pretty sure that it does not exist. Your best option, in my opinion is either using a uniform interface and extend it, or extend the prototypes from which your objects inherit (then you can use instanceof before going forward with the method call) or use the somewhat cumbersome '&&' operator in order to avoid the access of nonexistent properties/methods:
obj.methodName && obj.methodName(art1,arg2,...);
You can also extend the Object prototype with Anurag's suggestion ('call').
Solution 4:
You can also check if the method exists.
if(a['your_method_that_doesnt_exist']===undefined){
//method doesn't exist
}
Post a Comment for "Is There A Way To Catch An Attempt To Access A Non Existant Property Or Method?"