你能说这是 Javascript Closure 的一个正确的例子吗?我们需要考虑避免闭包的地方在哪里?
问题与原因
我的一位队友最终陷入了在 javascript 中实现函数挂钩的混乱局面。这是实际的代码
function ActualMethod(){
this.doSomething = function() {
this.testMethod();
};
this.testMethod = function(){
alert("testMethod");
};
}
function ClosureTest(){
var objActual= new ActualMethod();
var closeHandler = objActual.doSomething;
closeHandler();
closeHandler.apply(objActual,arguments); //the fix i have added
this.ActualTest = function() {
alert("ActualTest");
};
}
在上面的代码中,var closeHandler 是在 ClosureTest() 的上下文中创建的,但它保存了 ActualMethod.doSomething 的处理程序。每当调用 closeHandler() 时都会出现“对象不支持此方法”错误。
这是因为 doSomething() 函数调用了另一个名为 this.testMethod(); 的方法。这里 this 指的是调用者的上下文而不是被调用者。所以我假设 closeHandler 绑定到实际创建的环境(ClosureTest)。即使它将处理程序保存到另一个上下文,它也只是暴露了其自身上下文的属性。
解决方案
为了避免这种情况,我建议使用apply来指定它需要执行的上下文。
closeHandler.apply(objActual,参数);
问题
是关闭的完美场景吗??
你在 javascript 中遇到过哪些有趣的地方的闭包?
更新
是的,它很简单,我可以直接调用该方法。但问题是,在特定场景中,我需要拦截对实际方法的调用并在此之前运行一些代码,最后执行实际方法。
举个例子,我正在使用第 3 方 aspx 网格库,并且所有mouseclick 事件被它们的控件捕获。特别是通过鼠标单击进行分组,我需要拦截对其 ilbrary 方法的调用,并挂钩我的方法来执行,并将调用重定向到实际的库方法
希望这会有所帮助
Problem & Reason
One of my team mate ended up in messy situtaion implementing function hooking in javascript. this is the actual code
function ActualMethod(){
this.doSomething = function() {
this.testMethod();
};
this.testMethod = function(){
alert("testMethod");
};
}
function ClosureTest(){
var objActual= new ActualMethod();
var closeHandler = objActual.doSomething;
closeHandler();
closeHandler.apply(objActual,arguments); //the fix i have added
this.ActualTest = function() {
alert("ActualTest");
};
}
In the above code, var closeHandler is created in the context of ClosureTest(), but it holds the handler of the ActualMethod.doSomething. Whenever calling the closeHandler() ended up in "object doesnt support this method" error.
This is because doSomething() function calls another method inside called this.testMethod();. Here this refers to the context of the caller not callee.so i assume the closeHandler is bound to the environment(ClosureTest) actually created.Even though it holds the handler to the another context, it just exposes the properties of its own context.
Solution
To avoid this i suggest to use apply to specify the conext in which it needs to execute.
closeHandler.apply(objActual,arguments);
Questions
is it perfect scenario for closures..??
What are the intersting places you have encountered closures in javascript..?
UPDATE
Yes its simple i can call the method directly. but the problem is, in a particular scenario I need to intercept the call to actuall method and run some code before that, finally execute the actual method..
say for an example, am using 3rd party aspx grid library, and all the mouseclick events are trapped by their controls. In particular group by mouse click i need to intercept the call to their ilbrary method and hook my mthod to execute instead and redirect the call to actual library method
hope this helps
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新:因为您可能在代码中遗漏了一些细节,所以很难在不遗漏实际代码要点的情况下将其调整为可行的内容。我确实认为我理解您所描述的根本问题。我希望以下内容有所帮助。
假设下面这个简单的例子:
要拦截这样的方法调用,你可以这样做:
不幸的是,因为
method()
是在构造函数中定义的,而不是在原型上,所以你需要有一个对象实例来包裹物体。原始问题的答案:
doSomething()
函数用作使用ActualMethod()
创建的对象的方法。您应该将其用作方法,而不是将其分离并在不同的上下文中将其用作函数。为什么不直接调用方法呢?如果您将一个方法(某个对象上的函数)分配给 Javascript 中的局部变量并调用它,上下文将会不同(
this
的值会发生变化)。如果你不想让它发生,就不要这样做。Update: Because you probably left out some details in your code, it is difficult to adapt it into something workable without missing the point of your actual code. I do think I understand your underlying problem as you describe it. I hope the following helps.
Suppose the following simple example:
To intercept such a method call, you can do this:
Unfortunately, because
method()
is defined in the constructor function, not on a prototype, you need to have an object instance to wrap the object.Answer to original question: The
doSomething()
function is used as a method on objects created withActualMethod()
. You should use it as a method, not detach it and use it as a function in a different context. Why don't you just call the method directly?If you assign a method (a function on some object) to a local variable in Javascript and call it, the context will be different (the value of
this
changes). If you don't want it to happen, don't do it.当我想要挂钩一个函数时,我使用以下 Function 方法,这也是闭包演示的一个很好的部分:
然后执行类似以下操作:
proceed 绑定到其初始对象,因此您可以安全地调用它。
When I want to hook a function, I use the following Function method which is also a fine piece of Closure demonstration:
Then do something like:
proceed is bound to its initial object, so you can safely call it.