JS闭包和递归

时间:2013-06-19 09:53:45

标签: javascript recursion closures

例如,我有一个带闭包的函数:

function getData() {
    var status = 0;

    var func = function() {
        status++
        alert(status);
    }

    return func;
}

它的工作正常,变量“status”在闭包函数中可见。

但是如果我将闭包代码转移到单独的函数中,则闭包变量“status”不可用:

function getData() {
    var status = 0;

    var func = function() {
        myFunction();
    }

    return func;
}


function myFunction() {
     status++
     alert(status);
}

是的,我可以将此变量发送到函数,然后返回更改的值。但是如果我需要在“myFunction”中递归呢?

function getData() {
    var status = 0;

    var a = function() {
        myFunction(status);
    }
    return a;
}


function myFunction(status) {

     if (status == 0) {
          status = 1;
          // After calling this function again "status" will reset to 0, 
          // but I want to save current value (status = 1). 
          data();
     }
     return status++;

}

var data = getData();
data();

如何为闭包函数的所有调用获取变量“status”的一个实例。

谢谢!

3 个答案:

答案 0 :(得分:2)

首先,这不起作用,因为JS具有词法范围,而不是动态范围。 More info on Wikipedia

其次,如果你想将一个变量传递给一个函数,并允许该函数改变它,你需要发送一个instanceof对象的东西。

0 instanceof Object
false
"" instanceof Object
false
[] instanceof Object
true
({}) instanceof Object
true
(function(){}) instanceof Object
true

您可以将您的号码包装成一个对象并传递它。

修改示例:

function getData() {
    var o = {
        status: 0
    };

    var a = function () {
        myFunction(o);
    }
    return a;
}


function myFunction(o) {
    console.log(o);
    if (o.status == 0) {
        o.status = 1;
        // After calling this function again "status" will reset to 0, 
        // but I want to save current value (status = 1). 
        data();
    }
    return o.status++;
}

var data = getData();
data();

输出:

Object {status: 0}
Object {status: 1}

http://jsfiddle.net/Dogbert/Tw7nh/

答案 1 :(得分:1)

您可以替换此行:

myFunction(status);

使用:

status = myFunction(status);

或:

JSFIDDLE:http://jsfiddle.net/KHZRr/

function Data(){

    var status = 0;

    var a = {
        getData : function(){
            if( status == 0 ){
                status = 1;
                return "FIRST, status = " + status;
            }else{
                return "NOT FIRST, status = " + status;
            }
        }
    }
    return a;
}



var data = Data();
alert( data.getData() );
alert( data.getData() );
alert( data.getData() );

这是你在找什么?

答案 2 :(得分:0)

  

如果我将闭包代码转移到单独的函数中,则闭包变量“status”不可用。

是的,由于JavaScript的范围规则,这不会改变。

  

是的,我可以将此变量发送到函数,然后返回更改的值。但是如果我需要在“myFunction”中进行递归呢?

没有任何改变。你也可以在闭包内部使用递归。

function getData() {
    var status = 0;

    function data() {
        if (status++ == 0) {
            // do anything you want
            // including recursive calls to `data()`
        }
        return status;
    }

    return data;
}

getData()();