Reputation: 100051
In Rhino, I can add specific properties by defining js... functions on a Java class. What I'd like is to define a catchall function that gets called if a program goes to reference a property that hasn't been otherwise defined. Is there a way?
Upvotes: 0
Views: 1070
Reputation: 12811
I don't think there is a way to express this concept using native syntax, even using Rhino/Spidermonkey proprietary extensions like getters and setters: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Objects#Defining_Getters_and_Setters
However, JavaScript is fairly easy to extend, and so I think you could get something pretty close by adding a method to Object.prototype to support this more advanced style method invocation. The following would seem to do what you want:
Object.prototype.invokeMethodOrDefault = function(methodName,argsArray){
if(this[methodName] && typeof this[methodName] == "function"){
//invoke method with given arguments
this[methodName].apply(this,argsArray)
}else{
this.defaultMethod.apply(this,argsArray)
}
}
//add a defaultMethod noop that can be overridden for individual subclasses
Object.prototype.defaultMethod = function(){print("In default method")}
//test it
foo = {
helloWorld:function(){
print("hello world!")
print("args:")
for(var i=0,l=arguments.length;i<l;i++){
print(arguments[i]);
}
}
}
foo.invokeMethodOrDefault("thisMethodDoesNotExist",[])
foo.invokeMethodOrDefault("helloWorld",["arg1","arg2"])
bar = {
helloWorld2:function(){
print("hello world2!")
print("args:")
for(var i=0,l=arguments.length;i<l;i++){
print(arguments[i]);
}
},
defaultMethod:function(){
print("in new default method")
}
}
bar.invokeMethodOrDefault("thisMethodDoesNotExist",[])
bar.invokeMethodOrDefault("helloWorld2",["arg1","arg2"])
Which prints the following:
In default method
hello world!
args:
arg1
arg2
in new default method
hello world2!
args:
arg1
arg2
Upvotes: 2