4

这可能是一个愚蠢的问题,但由于所有“Closure 101”链接,我似乎无法利用谷歌......

总之,给定依赖于闭包上下文的重复代码,有没有办法将代码去重到函数调用中,同时仍然让新函数只依赖闭包而不是通过参数传递它需要的一切?

一个粗略的代码示例可能如下所示:

function doWork(){
    // initialize variables
    // manipulate variables
    // ...

    $.ajax({
       //...
       success: function(data){
           // DUPLICATE CODE INSTANCE 1 HERE
           // RELIES ON VARIABLES IN THE CLOSURE          
       }
    });

    // More code

    $.ajax({
       //...
       success: function(data){
           // DUPLICATE CODE INSTANCE 2 HERE
           // RELIES ON VARIABLES IN THE CLOSURE          
       }
    });

}

据我所知,如果我将成功块中的逻辑删除为

function onSuccess(...){
   // ...
}

然后 onSuccess 不再是闭包的一部分,因此需要所有闭包变量作为参数传递,当前逻辑正在使用闭包进行访问。

我对闭包的工作方式有误吗?有没有办法将闭包“传递给 onSuccess 函数”而不是传递单个变量?

4

3 回答 3

4

您对关闭行为没有错。您可以做的是onSuccessdoWork.

function doWork(...) {
  function onSuccess(...) {
    // ...
  }

  $.ajax({
    //...
    success: onSuccess
  });

  $.ajax({
    //...
    success: onSuccess
  });
}
于 2013-04-29T23:35:15.023 回答
2

除非你在闭包内定义它

function doWork(){
    // initialize variables
    // manipulate variables
    // ...
    function onSuccess(data){
       // DUPLICATE CODE INSTANCE 2 HERE
       // RELIES ON VARIABLES IN THE CLOSURE 
     }


    $.ajax({
       //...
       success: onSuccess
    });

    // More code

    $.ajax({
       //...
       success: onSuccess
    });

}
于 2013-04-29T23:34:26.557 回答
0

您可以做的是public通过使用this.var. 然后,您可以传递对this闭包范围之外的对象的引用,并访问您传递的闭包的属性和方法(从this)。以下面的代码为例:

根据@danp 的指导编辑:

var Work = function Work() {   
    this.closureVar = "hello";

    this.closureOnSuccess = function () {
        console.log("Inner call:" + this.closureVar);
    }

    this.someCall = function() {
        globalOnSuccess(this); //Give the global function a reference to this closure
        this.closureOnSuccess();
    }

    this.someCall();
}

var globalOnSuccess = function (context) { //context is a reference to a closure
    console.log("Outer call:" + context.closureVar); 
}; //Globally scoped function

var work = new Work();

jsFiddle

另一个例子:

var Work = function Work() {};

Work.prototype = {
    closureVar: "hello",
    closureOnSuccess: function () {
        console.log("Inner call:" + this.closureVar);
    },
    someCall: function () {
        globalOnSuccess(this);
        this.closureOnSuccess();
    }
};

var globalOnSuccess = function (context) {
    console.log("Outer call:" + context.closureVar);
};

var work = new Work();

work.someCall();

jsFiddle

于 2013-04-29T23:51:47.600 回答