调用其他对象函数的Eventmanager
我正在使用javascript和jQuery。 我有一个“问题”,我的网络应用程序有不同的视图,一个动作(如鼠标点击)应该在不同的视图中做不同的事情。
我创建了一个ActionManager,在触发click事件时会收到通知。 此管理器对象了解当前视图。 现在我不是动作管理员能够在不同的对象中触发一个function。
我所做的是经理获得不同对象的实例。 这是通过在初始化时进行注册来完成的,在那里他们注册了他们不想处理什么样的事件以及他们负责什么样的观点。
问题是我想让它尽可能通用,这样actionmanager就不需要知道将要调用的函数的名称是什么。 然后,不同的实例可以具有不同的函数名称,而不让动作管理器知道它。 我可以让注册部分通过发送对该函数的引用来存储该实例中该事件的函数名称,但是我不能这样做:
myfunc : function (myinstance, myfunction) { myinstance.myfunction(); }
假设myfunction()作为myinstance中的函数存在,而不是使用可能是“onMouseClick”的真实函数名。
编辑:其他人看到这个问题的解释并想知道原因:我的eventmanager的原因是我只想在需要它的元素上添加一个click事件,而不是更改click事件代码。 我还想只调用一个方法并在该方法中运行代码。 我不想调用几个方法,让方法根据视图决定它们是否应该运行。
如果myfunction
是一个字符串:
你可以这样做:
myfunc : function (myinstance, myfunction) { myinstance[myfunction](); }
对象上的函数只是分配给该对象上的属性的函数对象。 在JavaScript中,您可以通过以下两种方式之一访问属性:
- 使用虚线表示法和属性名称的文字,例如
x = obj.foo;
, 要么 - 使用括号表示法和字符串作为属性名称,例如
x = obj["foo"];
它们完全相同,但当然第二种forms更灵活 – 事实上,设计的确适用于您所描述的情况。
如果myfunction
是一个实际的函数对象:
你可以这样做:
myfunc : function (myinstance, myfunction) { myfunction.call(myinstance); }
这会调用myfunction
并确保在调用期间this = myinstance
。 所有JavaScript函数对象都有一个call
函数和一个apply
函数。 它们都做同样的事情(用特定的this
值调用函数),但它们在如何将参数传递给函数方面有所不同:
通过call
,您可以在call
调用中将它们作为离散参数传递:
func.call(inst, arg1, arg2, arg3);
使用apply
,您传入一组参数:
func.apply(inst, [arg1, arg2, arg3]); // ^----------------^---- note that this is an array
例如:
var a = [arg1, arg2, arg3]; func.apply(inst, a);
所有上述的例子
实时拷贝 – 因为你说你使用的是jQuery,所以我继续使用它以方便使用,但上面没有一个与jQuery有关,这就是vanilla JavaScript的工作方式。
var myinstance = { foo: "bar", myfunction: function(arg1, arg2) { display("
myfunction
called,this.foo
is: " + this.foo); if (arg1) { display("arg1
is: " + arg1); } if (arg2) { display("arg1
is: " + arg2); } } }; // Without arguments callUsingString(myinstance, "myfunction"); sep(); callUsingFunction(myinstance, myinstance.myfunction); sep(); // With arguments callUsingStringWithArgs(myinstance, "myfunction", ["one", "two"]); sep(); callUsingFunctionWithArgs(myinstance, myinstance.myfunction, ["one", "two"]); sep(); function callUsingString(inst, func) { inst[func](); } function callUsingFunction(inst, func) { func.call(inst); } function callUsingStringWithArgs(inst, func, args) { // Easier using the function reference: callUsingFunctionWithArgs(inst, inst[func], args); } function callUsingFunctionWithArgs(inst, func, args) { func.apply(inst, args); }
( display
只是将一个段落元素附加到具有给定文本的页面; sep
只是附加一个hr
元素。)
更多阅读:
- 神话方法
- 你必须记住
this
如果myFunction是一个字符串,你可以这样做。
myfunc : function (myinstance, myfunction) { myinstance[myfunction](); }
但是如果myFunnction是一个函数对象,则必须调用该函数。 myFunction中的this
对象引用myinstance
。
myfunc : function (myinstance, myfunction) { myfunction.call(myinstance); }
您可以这样做,但为什么不使用.bind()和.trigger()来处理事件? 演示http://jsfiddle.net/DnjRs/