JavaScript 库迭代器
JavaScript Library Iterators
我没有多少 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
不,您不需要在不同的函数中使用唯一的变量名称。
用 var
声明的变量在声明它们的函数范围内是局部的。它们不会也不会与该范围之外的任何内容发生冲突。因此,您的三个函数 watchSet()
、mathSum()
和 validateError()
都可以很好地使用 var i
,并且不会相互冲突或与这些函数之外的任何第三方代码发生冲突。像这样的局部变量在每次函数 运行 时都是唯一创建的,并且只能在该函数中引用。
如果您没有使用 var
显式声明您的循环变量,那么 Javascript 将 "implicitly" 使用该名称创建全局变量,然后,是的,您的不同函数可能会发生冲突如果执行此操作的一个函数调用另一个函数,那么它们都试图同时使用同一个全局变量。但是,只要你的变量是用 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 );
}
}
我没有多少 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
不,您不需要在不同的函数中使用唯一的变量名称。
用 var
声明的变量在声明它们的函数范围内是局部的。它们不会也不会与该范围之外的任何内容发生冲突。因此,您的三个函数 watchSet()
、mathSum()
和 validateError()
都可以很好地使用 var i
,并且不会相互冲突或与这些函数之外的任何第三方代码发生冲突。像这样的局部变量在每次函数 运行 时都是唯一创建的,并且只能在该函数中引用。
如果您没有使用 var
显式声明您的循环变量,那么 Javascript 将 "implicitly" 使用该名称创建全局变量,然后,是的,您的不同函数可能会发生冲突如果执行此操作的一个函数调用另一个函数,那么它们都试图同时使用同一个全局变量。但是,只要你的变量是用 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 );
}
}