JavaScript库迭代器

时间:2015-08-28 18:33:39

标签: javascript for-loop iteration

我没有太多的JavaScript经验。我的问题是: 当我编写JavaScript库时,我编写函数的许多函数都是为了相互调用,用户可以调用我可能没有的方式相互定义的函数。预测但是有效,如何将迭代器保持在具有迭代循环的函数中?

每次执行for循环时,我是否必须在for循环中为每个迭代器设置新名称,以确保我没有意外地在两个函数中使用相同的变量,其中一个函数可能在我无法预测或想到的情况下,在另一个内部筑巢?

这些只是其中包含迭代的函数的几个示例。我写的所有内容都是为了与Qualtrics调查进行交互(如下面的gif示例所示)。

function watchSet(set, mathFunction) {
    var setSize = set.length;
    for (var i=0; i < setSize; i++) {
        set[i].down().observe("keyup", mathFunction );
    }
}
function mathSum(set, output) {
    var setTotal = 0;
    for (var j=0; j < (set.length); j++) {
        var setInputValue = parseInt(set[j].down().value, 10);
        if (isNaN(setInputValue)) { setInputValue = 0; }
        setTotal = setTotal + setInputValue;
    }
    output.value = setTotal;
}
function validateError(array, color) {
    if (color === undefined) {
        color = "pink";
    }
    color = color.concat(";");
    for (var k=0; k < array.length; k++) {
        array[k].down().setAttribute("style", "background-color: ".concat(color));
    }
    $('NextButton') && $('NextButton').hide();
}

function cellRange(startCell, endCell) {
    var r1 = /^[A-Z]/;
    var r2 = /[0-9]{1,3}$/;

    var startCellColumn = r1.exec(startCell)[0].charCodeAt(0) - 61;
    var endCellColumn = r1.exec(endCell)[0].charCodeAt(0) - 61;
    var startCellRow = parseInt(r2.exec(startCell)[0], 10);
    var endCellRow = parseInt(r2.exec(endCell)[0], 10);

    var tempRange = [];
    for (var q=startCellColumn; q<=endCellColumn; q++) {
        for (var r=startCellRow; r<=endCellRow; r++) {
            tempRange.push(q);
            tempRange.push(r);
        }
    }

    var outputRange = [];
    for (var s=0; s < tempRange.length; s+=2) {
        outputRange.push(cell(String.fromCharCode(tempRange[s]+61).concat(tempRange[s+1])));
    }
    return outputRange;
}

Gif示例: setting equivalency-validation summing a couple cells

1 个答案:

答案 0 :(得分:2)

不,您不需要在不同的功能中使用唯一的变量名称。

使用var声明的变量是声明它们的函数作用域的局部变量。它们不会也不会与该作用域之外的任何内容冲突。因此,您的三个函数watchSet()mathSum()validateError()都可以正常使用var i,并且不会相互冲突或与这些函数之外的任何第三方代码冲突。这样的局部变量在每次运行函数时都是唯一创建的,并且只能从该函数中引用。

如果你没有使用var显式声明你的循环变量,那么Javascript将会隐含地#34;通过该名称创建全局变量然后,是的,如果执行此操作的一个函数调用另一个函数,则您的不同函数可能会发生冲突,因此他们都试图同时使用相同的全局变量。但是,只要您的变量使用var声明并且您的代码在函数中(因此不在全局范围内运行),就不会发生这种情况。

你也可以在strict mode中强制推荐你的代码(强烈推荐),因为一个意外的隐式全局是一个立即错误,解释器会立即显示问题所在。

或使用.forEach()

您也可以在数组上使用.forEach(),而不必创建自己的迭代索引。

function watchSet(set, mathFunction) {
    set.forEach(function(item) {
        item.down().observe("keyup", mathFunction );
    });
}

或者,在ES6环境中使用let

在ES6环境中,您可以使用let代替var,变量的范围也只限于for循环。

function watchSet(set, mathFunction) {
    var setSize = set.length;
    // when declaring with let in a for loop, the variable is scoped to
    // only inside the for loop
    for (let i=0; i < setSize; i++) {
        set[i].down().observe("keyup", mathFunction );
    }

    // with let in a for declaration, even another use in the same function
    // does not conflict
    // this is a completely different variable than the one above
    for (let i=0; i < setSize; i++) {
        set[i].up().observe("keyup", mathFunction );
    }
}