你能说这是一个合适的例子Javascript Closure ..在哪里的地方,我们需要考虑避免闭包? [英] can you say this is a right example of Javascript Closure.. Where the places we need to consider avoiding the closures?

查看:102
本文介绍了你能说这是一个合适的例子Javascript Closure ..在哪里的地方,我们需要考虑避免闭包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题&原因



我的一个队友结束了凌乱的situtaion在javascript中实现函数挂钩。这是实际的代码

  function ActualMethod(){
this.doSomething = function(){
this.testMethod();
};

this.testMethod = function(){
alert(testMethod);
};
}


函数ClosureTest(){
var objActual = new ActualMethod();
var closeHandler = objActual.doSomething;
closeHandler();
closeHandler.apply(objActual,arguments); //修复我添加了
this.ActualTest = function(){
alert(ActualTest);
};在上面的代码中,var closeHandler是在ClosureTest()的上下文中创建的。 ,但它保存ActualMethod.doSomething的处理程序。每当调用closeHandler()在对象不支持这个方法错误。



这是因为doSomething()函数调用另一个方法里面调用this.testMethod();.这里 this 指的是调用者的上下文not callee.so我假设closeHandler绑定到环境(ClosureTest)实际创建。虽然它持有另一个上下文的处理程序,它只是暴露

为了避免这种情况,我建议使用应用 strong>指定它需​​要执行的conext。


closeHandler.apply(objActual,arguments);



$ b b

问题



是封闭的完美场景。



你在javascript中遇到了关闭..?



UPDATE



我可以直接调用该方法。但是问题是,在一个特定的情况下,我需要拦截对actuall方法的调用并运行一些代码之前,最后执行实际的方法..



说一个例子,我使用第三方aspx网格库,所有的mouseclick事件被他们的控制捕获。特别是通过鼠标单击我需要拦截他们的ilbrary方法的调用和钩我的mthod执行,并重定向到实际库方法



希望这有助于

解决方案

更新:因为您可能在代码中遗漏了一些详细信息,很难适应它成为可行的东西,而不会丢失你的实际代码的点。我确实认为我理解你的根本问题,你描述它。我希望以下内容有所帮助。



假设有以下简单示例:

  //构造函数。 
function Example(){
//方法:
this.method = function(){
alert(original method);
}
}

//你可以这样使用它:
var obj = new Example();
obj.method(); //调用原始方法。

要拦截这种方法调用,您可以这样做:

  function wrap(obj){
var originalMethod = obj.method;
obj.method = function(){
alert(intercepted call);
originalMethod.apply(this,arguments);
}
return obj;
}

var obj = wrap(new Example());
obj.method(); //调用wrap方法。不幸的是,因为定义了 method(),所以


$ b在构造函数中,不是在原型上,你需要有一个对象实例来包装对象。






对原始问题的回答 doSomething()函数用作通过 ActualMethod()创建的对象的方法。你应该使用它作为一个方法,不要分离它,并在不同的上下文中使用它作为一个函数。为什么不直接调用方法?

 函数ClosureTest(){
var objActual = new ActualMethod );
//直接调用方法,避免使用apply()调用。
objActual.doSomething();
this.ActualTest = function(){
alert(ActualTest);
};
}

如果将一个方法在Javascript中调用它,上下文会有所不同( this 的值)。如果你不希望它发生,不要这样做。


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

解决方案

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:

// Constructor function.
function Example() {
    // Method:
    this.method = function() {
        alert("original method");
    }
}

// You would use it like this:
var obj = new Example();
obj.method(); // Calls original method.

To intercept such a method call, you can do this:

function wrap(obj) {
    var originalMethod = obj.method;
    obj.method = function() {
        alert("intercepted call");
        originalMethod.apply(this, arguments);
    }
    return obj;
}

var obj = wrap(new Example());
obj.method(); // Calls wrapped method.

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 with ActualMethod(). 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?

function ClosureTest(){
    var objActual = new ActualMethod();
    // Call method directly, avoid messy apply() calls.
    objActual.doSomething();
    this.ActualTest = function() {
        alert("ActualTest");
    };
}

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.

这篇关于你能说这是一个合适的例子Javascript Closure ..在哪里的地方,我们需要考虑避免闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆