Жизнь всего лишь великолепный цикл

JavaScript
Жизнь всего лишь великолепный цикл

написать впереди

В какой-то тайный сезон молодость уходит и никогда не повторяется. Может быть, это просто случайный фрагмент мысли, оставленный на ясном солнечном свете, но он все же может заставить наши глаза светиться слабым светом.

Эх, извините, я ошибся набором, я не буду сегодня говорить о Ли Иань, а давайте поговорим о цикле.

Эта статья о обходе цикла js, это не механизм циклов событий, и идея не глубокая.

1. Собственный цикл JS

1.1 пока цикл

Оператор while содержит условие цикла и блок кода, пока условие истинно, блок кода выполняется в непрерывном цикле.先判断后执行.

var num = 1;//1.声明循环变量
while (num<=10){//2.判断循环条件
	document.write(num+" ");//3.执行循环体
	num++;//4.跟新循环变量
}

1.2 делать... пока цикл

Цикл do...while подобен циклу while, единственное отличие состоит в том, что тело цикла выполняется один раз, а затем оценивается условие цикла. который先执行后判断.

var num = 10;
do{
	document.write(num+" ");
	num--;
}while(num>=0);
document.write(num);//-1

1.3 для цикла

Цикл for имеет три выражения: ① объявить переменную цикла, ② определить условие цикла, ③ обновить переменную цикла,先判断后执行, то же, что и пока.

for(var num=0;num<10;num++){
	document.write(num+" ");
}

1.4 Цикл for...in

Цикл for...in в основном используется для перебора объектов.

var obj = {a:1,b:2,c:3};
for(var i in obj){
	console.log('键名:'+i);
	console.log('键值:'+obj[i]);
}

Обратите внимание:

Цикл for...in может не только считывать свойства членов самого объекта во время обхода, но и продолжатьСеть прототиповЧтобы обойти свойство прототипа объекта, вы можете использоватьhasOwnPropertyОпределяет, является ли свойство свойством самого объекта.obj.hasOwnProperty(keys)==trueУказывает, что это свойство является свойством-членом объекта, а не свойством-прототипом.

var person = {name:'小夏'};
for(var key in person){
	if(person.hasOwnProperty(key)){
		console.log(key);//name
	}
}

Еще немного разговора: перебор объектов json

Неправильный массив json:

var json = [{qwer:'姚姚',a:'is',b:1}, {ob:'da',tp:'sb'}];
 
for(var i=0,l=json.length;i<l;i++){//此处长度用变量保存下来可节约资源的消耗
    for(var key in json[i]){
        alert(key+':'+json[i][key]);
    }
}

Обычный json-массив:

var packJson = [
    {"name": "nikita", "password": "1111"},
    {"name": "tony", "password": "2222"}
];
 
for (var p in packJson) {//遍历json数组时,这么写p为索引,0,1
    alert(packJson[p].name + " " + packJson[p].password);
}

1.5 for...of петель

Опираясь на языки C++, Java, C# и Python, ES6 представила цикл for...of как унифицированный способ обхода всех структур данных.

Структуру данных нужно только развернутьSymbol.iteratorимущество считается имеющимiteratorинтерфейс, вы можете использовать цикл for...of для перебора его членов. Другими словами, цикл for...of внутренне вызывает структуру данныхSymbol.iteratorметод. Диапазон циклов for...of, которые можно использовать, включает массивы, структуры Set и Map, а также некоторые подобные массивам объекты (такие какargumentsобъект,DOM NodeListобъект), позднееGeneratorобъекты и строки.

Пройдемся по некоторым структурам данных:

1.5.1 Массивы

var arr = ['a','b','c','d'];
for(let i in arr){
	console.log(i);//0 1 2 3
}
for(let j of arr){
	console.log(j);//a b c d
}
var iterator = arr.entries();
for(let j of iterator){
	console.log(j);//[0,"a"] [1,"b"] [2,"c"] [3,"d"]
}
var iterator = arr.keys();
console.log(iterator);
for(let j of iterator){
	console.log(j);//0 1 2 3
}

Приведенный выше код показывает, что цикл for...in считывает имя ключа, а цикл for...of считывает значение ключа. Если вы хотите получить индекс массива через цикл for...of, вы можете использовать экземпляр массиваentriesМетоды иkeysметод.

1.5.2 Структуры Set и Map

//Set 结构
var newSet = new Set(["a","b","c","c"]);
for(var e of newSet){
   console.log(e);//a b c
}

// Map结构
var es6 = new Map();
console.log(es6);
es6.set('yaoyao',1);
es6.set('bubu','2');
es6.set('fengfeng','last');
for(var [name,value] of es6){//用name和value接受键名和键值
   console.log(name+':'+value);//yaoyao:1 bubu:2 fengfeng:last
}

Приведенный выше код демонстрирует, как перемещаться по структурам Set и Map. Стоит отметить две вещи: во-первых, порядок обхода соответствует порядку, в котором элементы были добавлены в структуру данных. Во-вторых, при обходе структуры Set она возвращает значение, а при обходе структуры Map она возвращает массив, а два элемента массива — это имя ключа и значение ключа текущего члена Map соответственно.

1.5.3 Ряд объектов

Существует несколько классов массивоподобных объектов. Ниже приведен пример цикла for...of для строк, объектов DOM NodeList, объектов arguments.

// 字符串
var str = 'GREAT';
for(let s of str){
   console.log(s);//G R E A T
}
// DOM NodeList对象
let paras = document.querySelectorAll('p');
for(let p of paras){
   console.log(p);//打印出所有p标签
   p.classList.add('addClass');
}
// arguments对象
function printArgs(){
   for(let x of arguments){
   	console.log(x);
   }
}
printArgs([1,2],"1",{"a":3});//[1,2] "1" {"a":3}

1.6 Цикл Map()

Метод map передает все члены массива в функцию параметра по очереди, а затем возвращает результат каждого выполнения в новый массив без изменения исходного массива.

var numbers = [1,2,3];
var newNumbers = numbers.map(function(i){
   return i+1;
})
console.log(newNumbers);//[2,3,4]
console.log(numbers);//[1,2,3]

Метод карты принимает в качестве параметра функцию, и при вызове функции метод карты передает ей три параметра: текущее значение, текущий индекс и сам массив.

var newMap = [2,3,4].map(function(item,index,arr){
   return item*index;
})
console.log(newMap);//[0,3,8]

Кроме того, метод map также может принимать второй параметр, который используется для привязки переменной this внутри функции обратного вызова, указания объекта this внутри функции обратного вызова на второй параметр и косвенного управления этим параметром (обычно массивом).

var arr = ['a','b','c','d'];
var newArgs = [1,2].map(function(i){
   return this[i];
},arr);
console.log(newArgs);//["b","c"]

Приведенный выше код указывает объект this внутри функции обратного вызова на массив arr через второй параметр метода карты. Массив arr обрабатывается косвенно; описанная далее функция forEach также имеет эту функцию.

1.7 Цикл forEach()

Метод forEach очень похож на метод map тем, что он выполняет функцию параметра по очереди для всех элементов массива. Однако метод forEach не возвращает значение, он используется только для управления данными. То есть, если целью обхода массива является получение возвращаемого значения, используйте метод карты, в противном случае используйте метод forEach. Использование forEach такое же, как и у метода map.Параметр представляет собой функцию, которая также принимает три параметра: текущее значение, текущий индекс и сам массив.

[4,5,6].forEach(function(ele,index,arr){
	console.log(index+':'+ele);//0:4 1:5 2:5
})

Кроме того, цикл forEach, как и цикл map, также может использовать переменную this внутри связанной функции обратного вызова для косвенного управления другими переменными (см. пример цикла map() выше).

1.8 filter() цикл фильтрации

Метод filter используется для фильтрации элементов массива, а элементы, соответствующие условиям, формируют новый массив и возвращаются. Его параметр является функцией, все члены массива выполняют функцию по очереди, а члены, возвращаемый результат которых равен true, формируют новый возвращаемый массив. Этот метод не изменяет исходный массив.

var newFilter = [1,2,3,4,5,6].filter(function(i){
	return i>2
})
console.log(newFilter);//[3,4,5,6]

var arr = [0,1,'a',false,null,undefined];
var arrFilter = arr.filter(Boolean);
console.log(arrFilter);//[1,"a"]

Кажется, что он ничем не отличается от цикла Map(), поэтому, если вы сравните его, вы обнаружите, что когда оператор суждения используется внутри метода карты, он возвращает true, если он удовлетворен, и возвращает false, если он не удовлетворен. .

var newFilter = [1,2,3,4,5,6].map(function(i){
	return i>2
})
console.log(newFilter);//[false, false, true, true, true, true]

Функция параметров метода filter также может принимать три параметра: текущее значение, текущий индекс и сам массив.

var allFilter = [1,2,3,4,5].filter(function(ele,index,arr){
	return index % 2 === 0;
})
console.log(allFilter);//[1,3,5]

Метод фильтра также может принимать второй параметр, который используется для привязки переменной this внутри функции параметра.

var obj = {MAX:3};
var myFilter = function(item){
	return item > this.MAX;
}
var arr = [2,8,3,4,1,3,2,9];
var newFilter = arr.filter(myFilter,obj);
console.log(newFilter);//[8,4,9]

1.9 some(), every() выполняют цикл и подсчитывают, удовлетворяет ли массив определенному условию

Эти два метода аналогичны «утверждению» (assert), возвращая логическое значение, определяющее, соответствует ли член массива определенному условию. Они принимают функцию в качестве аргумента, и все члены массива по очереди выполняют эту функцию. Функция принимает три аргумента: текущее значение, текущий индекс и сам массив и возвращает логическое значение.

1.9.1 some()

Пока один член удовлетворяет условию, целое возвращает истину; в противном случае, если ни один член не удовлетворяет условию, целое возвращает ложь.

var arr = [1,2,3,4,5];
var newSome = arr.some(function(i){
	return i >= 3;
})
console.log(newSome);//true

1.9.2 every()

Если все члены удовлетворяют условию, целое возвращает истину; с другой стороны, пока один член не удовлетворяет условию, целое возвращает ложь.

var arr = [1,2,3,4,5];
var newEvery = arr.every(function(i){
	return i>=3;
})
console.log(newEvery);//false

1.10 уменьшить() и уменьшитьПраво()

1.10.1 reduce()

Метод reduce() принимает функцию как аккумулятор, и каждое значение в массиве (слева направо) сводится к значению.

[1, 2, 3, 4, 5].reduce(function (a, b) {
  console.log(a, b);
  return a + b;
})
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15

Сценарий: подсчитайте количество уникальных слов в массиве

Используйте цикл for

var arr = ['apple','orange','apple','orange','pear','orange'];
function getWordCnt(){
	var obj = {};
	for(var i=0,l=arr.length;i<l;i++){
		var item = arr[i];
		obj[item] = (obj[item]+1)||1;
		//第一次遍历obj.apple是undefined,所以obj.apple取1;
		//第二次遍历obj.orange是undefined,所以obj.orange取1;
		//第三次遍历obj.apple已经是1了,所以obj.apple = 1+1;······
	}
	return obj;
}
console.log(getWordCnt());//{apple: 2, orange: 3, pear: 1}

reduce(callback, initialValue) будет передавать две переменные. Функция обратного вызова (callback) и начальное значение (initialValue). Предположим, функция имеет входящий параметр, предыдущий и следующий, индекс и массив. Предыдущий и следующий обязательны, индекс и массив необязательны. Вообще говоря, prev начинается с первого элемента массива, а next — со второго элемента. Но когда вы передаете начальное значение (initialValue), первым prev будет начальное значение, а следующим будет первый элемент в массиве.

var arr = ['apple','orange','apple'];
function noPassValue(){
	return arr.reduce(function(prev,next){
		console.log('prev:',prev);
		console.log('next:',next);
		return prev+' '+next;
	})
}
console.log(noPassValue());
console.log('------------------------------');
function passValue(){
	return arr.reduce(function(prev,next){
		console.log('prev:',prev);
		console.log('next:',next);
		prev[next] = (prev[next]+1)||1;
		return prev;
	},{})
}
console.log(passValue());

Результат печати:

Наблюдая за результатами печати, можно не только четко определить разницу между ними, но и обнаружить, что функция passValue может быть эквивалентна приведенному выше циклу for.

1.10.2 reduceRight()

Синтаксис метода reduceRight и правила callback-функции такие же, как у метода reduce, разница в том, что он идет в порядке возрастания с сокращением, то есть индекс начинается с 0, а метод reduceRight в порядке убывания, т. е. то есть индекс начинается с arr.length-1.

Переверните строку:

var word = 'ilovexx';
function AppendToArray(previousValue,currentValue){
	return previousValue + currentValue;
}
var result = [].reduceRight.call(word,AppendToArray,"the ");
console.log(result);//the xxevoli

1.11 Object.keys()

Параметр метода Object.keys является объектом и возвращает массив. Членами этого массива являются все имена свойств самого объекта (а не унаследованные) и возвращаются толькоисчисляемыйхарактеристики.

var obj = {
  p1: 123,
  p2: 456
};
console.log(Object.keys(obj)); // ["p1", "p2"]

Если этот метод немного знаком, вы также можете сравнить приведенный выше 2.5.1.

1.12 Object.getOwnPropertyNames()

Метод Object.getOwnPropertyNames аналогичен методу Object.keys, он также принимает объект в качестве параметра и возвращает массив, содержащий все имена свойств самого объекта. Но он может возвращать неперечислимые свойства.

var a = ['Hello', 'World'];
console.log(Object.keys(a) )// ["0", "1"]
console.log(Object.getOwnPropertyNames(a)) // ["0", "1", "length"]

2. Обход с помощью jQuery

2.1 Массив обхода фильтра $.grep()

Цикл grep() может проходить по массиву, фильтровать элементы, соответствующие условиям, формировать новый массив и возвращаться.

$(function(){
    var array = [1,2,3,4,5,6,7,8,9];
    var filterarray = $.grep(array,function(value){
        return value > 5;//筛选出大于5的
    });
	console.log(filterarray);//[6,7,8,9]
    for(var i=0;i<filterarray.length;i++){
        alert(filterarray[i]);
    }
    for (key in filterarray){
        alert(filterarray[key]);
    }
})

2.2 Фильтр $.each() для обхода массива или объекта json

$.each(anObject,function(name,value) {
	console.log(name);
	console.log(value);
});
var anArray = ['one','two','three'];
$.each(anArray,function(n,value){
	console.log(n);
	console.log(value);
});

2.3 Массив обхода фильтра $.inArray()

var anArray = ['a','b','c'];
var index = $.inArray('b',anArray);
console.log(index,anArray[index]);//1 "b"

2.4 Массив обхода фильтра $.map()

var strings = ['0','1','2','3','4','5','6'];
var values = $.map(strings,function(val){
	var result = new Number(val);
	return isNaN(result)?null:result
})
for(var key in values){
	console.log(values[key]);
}

Метод обхода jQuery относительно редко используется в повседневном использовании, потому что эти методы могут найти соответствующие методы в нативном js. Написав так много, я обнаружил, что цикл for чаще всего используется в реальном бою, хахахахаха. . . . . . Однако, изучив их, по крайней мере, есть больше решений проблемы цикла в будущем, почему бы не сделать это.

3. Резюме - Сравнение - Посмотрите на сходства и различия

На самом деле сравнение большинства похожих методов уже обсуждалось в тексте, здесь map(), forEach() и filter() сравниваются по отдельности для сравнения:

Одинаковый:

1. Три петли не могут быть остановлены посередине, и все элементы всегда будут пройдены.

2. Все они могут принимать второй параметр, который используется для привязки переменной this внутри функции обратного вызова, указывать объект this внутри функции обратного вызова на второй параметр и косвенно управлять этим параметром (обычно массивом).

разница:

Цикл forEach() не имеет возвращаемого значения, цикл map(), filter() имеет возвращаемое значение.

4. Ссылки

Вы все еще используете для петлей?
15 видов обхода циклов js, сколько вы освоили?
Подробное изучение циклов for в JavaScript
Циклы в JS --- наиболее полное описание циклов