Я написал функцию, которая генерирует цепочку, функция valueOf
и контекст this
постоянно обновляется новой суммой, независимо от того, сколько аргументов передается каждый раз.
/* add function */
function add() {
"use strict";
var args, sum, chain;
args = Array.prototype.slice.call(arguments);
sum = typeof this === 'number' ? this : 0;
sum += args.reduce(function (p, n) { return p + n; }, 0);
chain = add.bind(sum);
chain.valueOf = function () {
return sum;
};
return chain;
}
/* tests */
console.log('add(1, 2) = ' + add(1, 2));
console.log('add(1)(2) = ' + add(1)(2));
/* even cooler stuff */
console.log('add(1, 2)(3) = ' + add(1, 2)(3));
console.log('add(1, 2, 3)(4, 5)(6) = ' + add(1, 2, 3)(4, 5)(6));
/* retains expected state */
var add7 = add(7);
console.log('var add7 = add(7)');
console.log('add7(3) = ' + add7(3));
console.log('add7(8) = ' + add7(8));
Причина, по которой требуются оба механизма, состоит в том, что следующий вызов в цепочке не может получить доступ к пользовательскому valueOf
функции привязки и любой скрипт, пытающийся оценить функцию как номер не может получить доступ к его контексту.
Единственным недостатком является требование strict mode
, чтобы this
оставался примитивным.
Вот отредактирование для поддержки обоих strict mode
и нестрогий режим:
function add() {
var args, sum, chain;
args = Array.prototype.slice.call(arguments);
// Number object from non-strict mode
if (this instanceof Number) {
sum = Number(this);
// number primitive from strict mode
} else if (typeof this === 'number') {
sum = this;
// initial call to add
} else {
sum = 0;
}
sum += args.reduce(function (p, n) { return p + n; }, 0);
chain = add.bind(sum);
chain.valueOf = function () {
return sum;
};
return chain;
}
Итак, несколько вещей:
setInterval()
, поддерживает ссылку на x
, а не значение снимка x
, так как существовал во время каждой конкретной итерации. Таким образом, поскольку x
изменяется в цикле, оно также обновляется в каждой из функций обратного вызова. for...in
используется для перечисления свойств объекта и может вести себя неожиданно при использовании на массивах. setTimeout()
, а не setInterval()
. Вы можете передать аргументы в функцию обратного вызова, предоставив дополнительные аргументы для setTimout()
:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
Числа будут передаваться по значению, а не по ссылке. Вот пример:
var list = [1,2,3,4];
for (var x = 0, ln = list.length; x < ln; x++) {
setTimeout(function(y) {
console.log("%d => %d", y, list[y] += 10);
}, x * 500, x); // we're passing x
}
var list = [1, 2, 3, 4, 5];
for (var i = 0, len = list.length; i < len; i += 1) {
(function(i) {
setInterval(function() {
list[i] += 10;
console.log(i + "=>" + list[i] + "\n");
}, 5000)
})(i);
}
Вот рабочий код:
var list = [1, 2, 3, 4, 5];
for (var i = 0, len = list.length; i < len; i += 1) {
(function(i) {
setInterval(function() {
list[i] += 10;
console.log(i + "=>" + list[i] + "\n");
}, 5000)
})(i);
}
Здесь индекс i
хранится в анонимном функция, чтобы она не перезаписывалась последовательными циклами. Функция setInterval
в вашем коде сохраняет ссылку только на последнее значение i
.
Вам не нужно использовать цикл for с оператором setInterval
. Попробуйте это:
var list = Array(...);
var x = 0;
setInterval(function() {
if (x < list.length;) {
list[x] += 10;
console.log(x+"=>"+list[x]);
}
else return;
x++;
}, 5000);
Я не знаю, как сделать это с помощью цикла for, но этот код здесь будет распечатывать каждый элемент в массиве через определенные интервалы времени:
function displayText(str) {
$('.demo').append($('<div>').text(str));
}
var i = 0;
var a = [12, 3, 45, 6, 7, 10];
function timedLoop() {
setTimeout(function () {
displayText(a[i]);
i++;
if(i < a.length) {
timedLoop();
}
}, 2000)
}
timedLoop();
Использование немного jquery, чтобы показать его в браузер.
Если у вас есть массив JSON и jQuery, вы можете использовать:
$.each(jsonArray, function(i, obj) {
setInterval( function() {
console.log(i+' '+obj);
}, 10);
});
Вы можете комбинировать forEach
и setTimeout
, чтобы зациклить массив с интервалом.
let modes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let interval = 1000; //one second
modes.forEach((mode, index) => {
setTimeout(() => {
console.log(mode)
}, index * interval)
})