我想创建一个javascript对象,我可以调用任何方法,而不必定义它们。理想情况下,我可以将其称为函数,它将调用一个函数,我将函数的名称称为其参数。
所以我会用callMethod(methodName)
方法定义一个对象,当我调用
thisObject.doAThing();
它会调用thisObject.callMethod("doAThing");
这可以在javascript中使用吗?
答案 0 :(得分:1)
不,那是不可能的。如果JavaScript对象没有属性,则不能将未定义的值视为方法。
答案 1 :(得分:1)
至少在Firefox中,您可以使用魔术方法__noSuchMethod__
来实现目标:
var o = {}
o.__noSuchMethod__ = function(id, args) { alert(id + args); }
o.foo(2,3) //will alert "foo" and "2,3"
请注意,这不是标准,正在考虑删除,因此it will not be added to V8。
答案 2 :(得分:0)
原帖(对不起,应该在q评论中提出这个问题):
我很难看清楚这一点。如果callMethod可以在某处访问'doAThing'方法,那么为什么不能在实例化对象时或者当callMethod的源添加了新方法时将其插入?
不要试图诋毁你。只是试着看看是否可能在疯狂疯狂世界的某个地方调用/应用/原型范例,它可以适应你希望以其他方式实现的目标。
在此评论后添加了编辑:
我想创建一个代理对象,将其调用委托给另一个 宾语。 - msfeldstein
好的,原型可能就是答案,因为它基本上可以作为对象本身没有的方法的后备。每个函数都有一个原型属性,基本上只是一个简单的vanilla对象。当函数用作构造函数时,分配给构造函数原型的方法和属性将成为构造函数实例的后备,当您调用它们没有的属性时。您可以向该原型对象添加属性,它们将有效地用于已创建的实例。所以在关联对象的情况下,我正在考虑这样的事情:
//A js constructor is just a function you intend to invoke with the 'new' keyword
//use of 'this.property' will make that property public in the instance
//var effectively makes it private
//Constructors funcs differ from classes in that they don't auto-handle inheritance down to other constructors. You have to come up with a prototype merging scheme to do that.
function MyFacadeConstructor(){ //expected args are objects to associate
var i = arguments.length; //arguments is a collection of args all funcs have
while(i--){
var thisObj = arguments[i];
associateObjMethods(thisObj);
}
//makes it public method but allows function hoisting internally
this.associateObjMethods = associateObjMethods;
function associateObjMethods(obj){
for(var x in obj){
if(obj[x].constructor.name === 'Function'){ //normalize for <= IE8
MyFacadeConstructor.prototype[x] = obj[x];
//or if we literally want the other method firing in its original context
//MyFacadeConstructor.prototype[x] = function(arg){ obj[x](arg); }
//Not sure how you would pass same number of arguments dynamically
//But I believe it's possible
//A workaround would be to always pass/assume one arg
//and use object literals when multiple are needed
}
}
}
}
function FirstNameAnnouncer(){
this.alertFirst = function(){
alert('Erik');
}
}
var fNamer = new FirstNameAnnouncer();
var newFacade = new MyFacadeConstructor(fNamer);
//newFacade.alertFirst should work now;
newFacade.alertFirst();
//but we can also associate after the fact
function LastNameAnnouncer(){
this.alertLast = function(){ alert('Reppen'); }
}
var lNamer = new LastNameAnnouncer();
newFacade.associateObjMethods(lNamer);
//now newFacade.alertLast should work
newFacade.alertLast();
现在,如果你想让调用对象的上下文重要,我会推荐一个事件驱动的接口,这是JS非常适合的。如果您正在寻找的门面方法的任何方面我都没有在这里实现,请告诉我。