阅读 310

JS技巧: 循环、遍历、迭代

大家好, 我是echo. 一名刚毕业的应届生.最近再学习Vue源码和看小黄书上卷.从平时摸鱼中学习一些js技巧和一些问题的解决方案. 在这里,分享自己的一些的解决方案和一些数组循环、遍历和迭代的知识分享.有不对的地方和有更好的解决方案,请大佬积极指出.

本文主要以实例引入, "纸上得来终觉浅,绝知此事要躬行"。更好的记忆莫过于coding.

1. 输入任意两个数值数组求交集

const arr = [1, 3, 5, 3, 3]
const brr = [2, 4, 6, 3]
复制代码
1.1 方法一 核心filter方法
function foo(a = [], b = []){
	a = [... new Set(a)];
	b = [... new Set(b)];
	if(a?.length > b?.length){
		return changeArr(a, b);
	}else{
		return changeArr(b, a);
	}
	function changeArr(arrMax, arrMin){
		return arrMin.filter(value => {
			if(arrMax.includes(value)){
				return value;
			}
		})
	}
}
复制代码
1.2 方法二 核心find方法
function foo(arr, brr) {
	let midArr = [];
	arr.forEach(value => {
		brr.find(val => val === value && midArr.push(val));
	})
	return [... new Set(midArr)];
}
let result = foo(arr, brr);
console.log(...result);
复制代码

2.求数值数组的最大数值

2.1 方式一 核心sort方法
const arr = [
	{
		name: 'echo0',
		age: 9
	},
	{
		name: 'echo1',
		age: 6
	},
	{
		name: 'echo2',
		age: 12
	}
];
function findMaxArrNum(arr){
	arr.sort((a, b) => b.age-a.age); //求最小值b-a 改为a-b
	return arr.slice(0, 1)[0];
}
let result = findMaxArrNum(arr);

复制代码
2.2 方式二 核心Math内置对象方法
const maxNum = Math.max(...arr.map(item => item.age));
const minNum = Math.min(...arr.map(item => item.age));
console.log(`${maxNum}, ${minNum}`);
复制代码
2.3 方式三
针对简单数值的数组使用sort()、reverse()、slice()进行组合获取;
复制代码

3.判断是否是在浏览器环境下

console.log(typeof(window) !== undefined);
复制代码

4.判断是否是一般的object对象

let obj2 = {
	name: 'echo'
};
console.log(Object.prototype.toString.call(obj2));
Object.prototype.toString.call(obj2) === "[object Object]";
复制代码

5.数组剔除空元素

需求: 针对数组中获取到的数据,剔除掉null、undefined、“”

let uuArr = [1, null, 2, undefined, '', 8];

console.log(Array.from(uuArr, item => {
	if(item > 5){
		return item;
	}
}));//[undefined, undefined, undefined, undefined, undefined, 8]
console.log(uuArr.map(item => item)); // [1, null, 2, undefined, "", 8]
console.log(uuArr.filter(item => item)); // [1, 2, 8]
复制代码

6. 数组遍历

6.1 filter()、find()

对于我们想对数组内的每一个元素进行操作判断则可以使用forEach() 常见处理数组都类似如下数组

let uArr = [
	{
		name: 'echo0',
		age: 6
	},
	{
		name: 'echo1',
		age: 66
	},
	{
		name: 'echo2',
		age: 666
	},
]
uArr.filter(item => item.age > 65); // 返回满足条件的所有元素
uArr.find(item => item.age > 65); // 返回满足条件的第一个元素 找到然后就return item
复制代码
6.2 some()、every()
uArr.some(item => item.age > 65); //查找到任一元素满足即return item ps: 返回的是布尔值
uArr.every(item => item.age > 65); //数组中任意元素不满足条件则返回false 都满足返回true ps:返回的是布尔值
复制代码
6.3 for in、 for of
6.3.1 for...in

for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

例如:

var myObject = {};;
Object.defineProperty(
	myObject,
	'a',
	{ enumerable: true, value: 2}
)

Object.defineProperty(
	myObject,
	'b',
	{ enumerable: false, value: 3}
)

console.log(myObject.b); // 3
console.log('b' in myObject); // true
console.log(myObject.hasOwnProperty("b")); //true

for (let key in myObject){
	console.log(key, myObject[key]);  // a 2 (for in 遍历得是可枚举的)
}

let firstMap = new Map([
	['name', 'echo'],
	['age', 6],
])
let firstSet = new Set([1, 2, 3, 4, 5]);
for (let key in firstSet){ //key in firstMap
	console.log(key);
}
console.log(firstSet);
//对于Map和Set for in是不行的 MDN文档介绍 可以使用for of 进行迭代
复制代码
6.3.2 for...of

for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

可迭代对象的原型对象上都有一个Symbol.iterator 方法

for (let value of myObject){
	console.log(value); //TypeError: myObject is not iterable
}
console.log(Object());
复制代码
6.3.3 小结
  1. for...in遍历对象...(可枚举)属性 (obj 遍历的是 key, array 遍历的是 下标)
  2. for...in遍历顺序是无序的尽量使用于对象(类数组将无序转为有序)
  3. for...of遍历的可迭代对象 (Object类型不行 遍历的是value)

7 生成器

7.1 生成器函数
let iteratorObj = new Set([1, 2])
function* makeRangeIterator(data) {
	for(let value of data){
		yield value;
	}
}
let a = makeRangeIterator(iteratorObj);
console.log(a); //makeRangeIterator {<suspended>} 返回的是一个Generator迭代器
console.log(a.next()); //console.log(a.next())
console.log(a.next()); //{value: 2, done: false}
console.log(a.next()); //{value: undefined, done: true}
复制代码
7.2 实现iterator
function iterator(arr){
	let index = 0 ;
	return {
		next(){
			return index >= arr.length ? {
				value: undefined,
				done: true
			} : {
				value: arr[index++],
				done: false
			}
				
		}
	}
}
let ioio = iterator([1,2,3]);
console.log(ioio.next()); //{value: 1, done: false}
console.log(ioio.next()); //{value: 2, done: false}
console.log(ioio.next()); //{value: 3, done: false}
console.log(ioio.next()); //{value: undefined, done: true}
复制代码

8. 数组求和

const prr = [1, 2, 3, 4, 5, 6];

8.1 reduce()
prr.reduce((accumulator, currentValue) =>  accumulator + currentValue) // 21
复制代码
8.2 forEach()
var total = 0
prr.forEach(value => {
	total += value
})
复制代码

9.扁平化数组

let flattened = [[0, 1], [2, 3], [5, 6]];

9.1 flat()
flattened.flat();//[0, 1, 2, 3, 5, 6]
复制代码
9.1.1 flat()实现 单层
function myFlat(brr) {
	let unfoldArr =  [];
	for( item of brr ) {
		Array.isArray(item) ?  unfoldArr.push(...item) : unfoldArr.push(item);
	}
	return unfoldArr
}
复制代码
9.1.2 flat()实现 递归实现多层
function myFlatMore(brr) {
	let unfoldArr =  [];
	for( item of brr ) {
		(Array.isArray(item)) ? unfoldArr.push(...myFlatMore(item)) : unfoldArr.push(item)
	}
	return unfoldArr
}
复制代码
9.2 reduce()
flattened.reduce((accumulator, currentValue) => accumulator.concat(currentValue));
复制代码

10 ...代替文字

10.1 css样式
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
复制代码
10.2 文字切割加拼接
function textFormat(text, num){
	return text.slice(0, num) + '...';
}
console.log(textFormat('JavaScript', 4))
复制代码

写在最后:

平平凑凑凑够10条,希望对你有所帮助,巩固js基础.如果更好的方法,建议评论分享.一起进步,成为一名优秀的前端工程师。

往期js文章

深浅拷贝方法总结、练习

几分钟了解js的模块化、IFEE

JavaScript实现封装、继承、多态

文章分类
前端
文章标签