I'm looking for a way to handle calls to undefined methods and properties in JavaScript.
These would be similar to the PHP magic methods __call, __callStatic, __get.
An example of the code using this might be:
var myObject = {};
myObject.__call = function (called, args) {
alert(called);
alert(args);
return(true);
}
myObject.meow("kitty", "miau");
This woul开发者_C百科d result in the first alert dialog displaying "meow" and the second to display "kitty, miau".
Proxy
can do it! Proxy can do EVERYTHING! An answer is given here: Is there a javascript equivalent of python's __getattr__ method? . To rephrase in my own words:
var myObject = new Proxy({},{get(target,name) {
return function() {
alert(name)
console.log(arguments) // alerts are bleh
return true
}
}})
myObject.meow("kitty", "miau") // alerts "meow", logs ["kitty","miau"] to the console, and returns true
Check out the MDN docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Works in chrome, firefox, and node.js. Downsides: doesn't work in IE - freakin IE. Soon.
If you just want something like PHP's features, read the following solution I came up with. I'm assuming that you'll be putting this functionality on your own objects. Well, as long as they're not functions, you can have the following convention for convenience, and it should work on all browsers:
instead of myobj.foo or myobj['foo'], just use myobj('foo'), and make your object callable when you define it. But you'll have to avoid the use of "new" because "new" can never return a function in Javascript.
var NewFlexible = function() {
var custom = {};
return function(prop) {
if (!(prop in custom)) custom.prop = null;
return custom.prop;
};
};
And then you can create objects like so:
myObj = NewFlexible();
Using something similar to the Douglas Crockford pattern, you could create "classes" that extend this:
var NewDerived = function(options) {
var result = {};
NewFlexible.apply(result, arguments); // parent constructor
// go on to do what you have to do
return result;
};
Or, to forget about constructors, you can just make a wrapper around objects:
var MakeFlexible = function (obj) {
return function(prop) {
if ('prop' in obj) return obj.prop;
obj.prop = null; return obj.prop;
};
}
You'll just have to publish this documentation for all users of your code. It's actually good to expose your functionality through this convention because you don't want to freak people out by using nonstandard javascript.
There is a magic function in Javascript called __noSuchMethod__. Here's an example:
var foo = { __noSuchMethod__ : function(name,params) { alert('invalid function call'); } }
foo.bar();
EDIT: As @jldupont mentioned, this is actually only in Rhino and SpiderMonkey (Mozilla's JS engine); it is not supported in the ECMAScript standard. There are some requests that it be in ECMAScript 4.
I should add for people still looking for a solution, there is this:
var myObject = {};
myObject['dynamicMethod'] = new function (parameters) {
alert(parameters);
};
The only difference here is that you may have to iterate over what you intend on adding. This is pre-generating the methods, instead of simply dynamically handling them.
If you are looking specifically for a method, you will have to wait until ES7, because it looks they arent going to include it that way in harmony, anyway, there is a currently working-standard functionality on this, trought the built-in object Proxy, that is added in ES6, i wrote an answer, in this question, that takes the problem in a wider manner. Basically involves wrapping the object into a proxy, an loading a handler
get: function(obj, propname) {custom handling}
into the proxy trought it´s constructor, to handle, filter or implement all requests of properties into it.
And it adds even more functionality.... For the complete answer, go into the link.
精彩评论