丢失递归调用的范围

时间:2015-05-07 21:39:46

标签: javascript recursion scoping

我正在创建一个接受数据集和整数n的模块,并且一次用n个产品递归填充该数据集,在第一次调用之后,该函数会丢失其范围和错误。为什么,以及解决这个问题的最佳做法是什么?

代码:

function ProductFactory(){

    var bigArr = [0,1,2,3,4,5,6,7,8,9];
    var smallArr = [1,2,3,4];

    return {
        getProductList: getProductList,
        getAllProducts: getAllProducts
    };

    function getProductList(start, size){ return start < 5 ? bigArr : smallArr }

    function getAllProducts(batchSizeRequested, dataSet) {
        var startPage = dataSet.length / batchSizeRequested;
        var productBatch = this.getProductList(startPage, batchSizeRequested);
        dataSet = dataSet.concat(productBatch);
        if (productBatch.length === batchSizeRequested)
            getAllProducts(batchSizeRequested, dataSet);
    }
}

var productGetter = new ProductFactory();

productGetter.getAllProducts(10, []);

2 个答案:

答案 0 :(得分:2)

1)首先,您不应该使用getProductList来呼叫this,在这种情况下,您可以按原样调用它,因为getProductList不是一个函数直接分配给此对象。它只是一个在其代码中使用局部变量的闭包。如果您想使用this来呼叫功能,则应使用this进行分配,例如 this.getProductList = function() {}
2)我不认为除了多余的this之外还有其他范围问题,但我发现了另一个问题。 你实际上并没有从你的函数返回任何东西,加上递归调用没有退出点 固定代码看起来像这样。

function ProductFactory(){

    var bigArr = [0,1,2,3,4,5,6,7,8,9];
    var smallArr = [1,2,3,4];

    return {
        getProductList: getProductList,
        getAllProducts: getAllProducts
    };

    function getProductList(start, size){ return start < 5 ? bigArr : smallArr }

    function getAllProducts(batchSizeRequested, dataSet) {
        var startPage = dataSet.length / batchSizeRequested;
        var productBatch = getProductList(startPage, batchSizeRequested);
        dataSet = dataSet.concat(productBatch);
        if (productBatch.length === batchSizeRequested) {
            return getAllProducts(batchSizeRequested, dataSet);
        } else {
            return dataSet;
        }
    }
}

var productGetter = ProductFactory();
var products = productGetter.getAllProducts(10, []);

console.log(products)

答案 1 :(得分:0)

这样的函数调用的典型方法是为this分配一个外部值(通常称为self):

function ProductFactory(){
  ...
  var self = this;
  function getAllProducts(batchSizeRequested, dataSet) {
    ...
    getAllProducts.apply(self, [batchSizeRequested, dataSet]);
  }
}

但是,在这种情况下,请尝试记住您已经定义了一个只能在构造函数内部私有访问的闭包函数getAllProducts。相反,你应该这样做:

function ProductFactory(){
  ...
  var self = this;
  this.getAllProducts = function(batchSizeRequested, dataSet) {
    ...
    self.getAllProducts(batchSizeRequested, dataSet);
  }
}