我正在寻找一种方法来处理JavaScript中未定义的方法和属性的调用。
这些类似于PHP魔术方法__call,__ callStatic,__ get。
使用此代码的示例可能是:
var myObject = {};
myObject.__call = function (called, args) {
alert(called);
alert(args);
return(true);
}
myObject.meow("kitty", "miau");
这将导致第一个警告对话框显示“喵”,第二个显示“kitty,miau”。
答案 0 :(得分:5)
Proxy
可以做到!代理可以做一切!这里给出了答案:Is there a javascript equivalent of python's __getattr__ method?。用我自己的话来改写:
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
查看MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
适用于chrome,firefox和node.js.缺点:在IE中不起作用 - freakin IE。很快。
答案 1 :(得分:0)
如果您只想要PHP的功能,请阅读我提出的以下解决方案。我假设你将把这个功能放在你自己的对象上。好吧,只要它们不是函数,为方便起见,您可以使用以下约定,它应该适用于所有浏览器:
而不是myobj.foo或myobj ['foo'],只需使用myobj('foo'),并在定义时使对象可调用。但是你必须避免使用“new”,因为“new”永远不能在Javascript中返回一个函数。
var NewFlexible = function() {
var custom = {};
return function(prop) {
if (!(prop in custom)) custom.prop = null;
return custom.prop;
};
};
然后你可以像这样创建对象:
myObj = NewFlexible();
使用与Douglas Crockford模式类似的东西,你可以创建扩展它的“类”:
var NewDerived = function(options) {
var result = {};
NewFlexible.apply(result, arguments); // parent constructor
// go on to do what you have to do
return result;
};
或者,忘记构造函数,你可以只为对象创建一个包装器:
var MakeFlexible = function (obj) {
return function(prop) {
if ('prop' in obj) return obj.prop;
obj.prop = null; return obj.prop;
};
}
您只需要为代码的所有用户发布此文档。通过这种约定公开你的功能实际上是好的,因为你不想通过使用非标准的javascript来吓跑人们。
答案 2 :(得分:-1)
Javascript中有一个名为__noSuchMethod__的魔术函数。这是一个例子:
var foo = { __noSuchMethod__ : function(name,params) { alert('invalid function call'); } }
foo.bar();
编辑:正如@jldupont所提到的,这实际上只是在Rhino和SpiderMonkey(Mozilla的JS引擎)中; ECMAScript标准不支持它。有一些请求是在ECMAScript 4中。
答案 3 :(得分:-1)
我应该为仍在寻找解决方案的人添加,有:
var myObject = {};
myObject['dynamicMethod'] = new function (parameters) {
alert(parameters);
};
这里唯一的区别是你可能需要迭代你想要添加的内容。这是预先生成方法,而不是简单地动态处理它们。
答案 4 :(得分:-1)
如果你正在寻找一种方法,你将不得不等到ES7,因为看起来他们不会以这种方式包含它,无论如何,目前有一个工作标准的功能, -in object Proxy,在ES6中添加,我在this question中写了一个答案,以更广泛的方式解决问题。 基本上涉及将对象包装到代理中,加载处理程序
get: function(obj, propname) {custom handling}
进入代理服务器构建器,处理,过滤或实现所有请求属性。
它增加了更多功能......如需完整答案,请进入链接。