前端遍历有多种情况,除最常用的for循环外,还有for in、for of 等等,有针对数组的map遍历、forEach遍历,有针对对象的Object.keys、object.values等等。
先说说数组,举个栗子。
var arr = [1,2,3];
arr.a = 4;
Array.prototype.name = 'mapbar_front';
for(var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
//普通的for循环打印出来是 1,2,3
for(var i in arr){
console.log(arr[i]);
}
//for in 循环打印的是 1,2,3,4,mapbar_front
for(var i of arr){
console.log(i);//这里是i,而不是arr[i]
}
//打印出来的是 1,2,3;
再说说对象的遍历
var obj = {
name: 'mapbar_front',
age: 28,
}
Object.prototype.work = 'do work!';
for(var i in obj) {
console.log(obj[i]);
}
var keylist = Object.keys(obj);
console.log(keylist);// ['name', 'age']
//hasOwnProperty的使用
console.log(obj.hasOwnProperty('name'));//true
console.log(obj.hasOwnProperty('work'));//false
任何的数组操作,都离不开遍历,但是因为需求不一样,所有会有不同的方法。
如果你想对数组中的每一项,执行某一个函数,可能你需要用到forEach方法:
var arr = [1,2,3];
arr.forEach((item, index) => {
console.log(item, index);
//也可以有其他的操作。
})
如果你想对数组,做某一种处理,返回一个处理后的数组,map方法可能就是你的想要的:
var arr = [1, 2, 3];
//给每一项乘以2,然后返回一个结果
var newarr = arr.map((item, index) => {
return item * 2;
})
如果你想对数组,筛选出符合条件的项,最终得到一个新的筛选后的数组,可能你要用到filter方法:
var arr = [1, 2, 3, 4];
var newarr = arr.filter((item, idx) => {
return item % 2 === 0;
})
如果你想要知道,我们的数组是不是有那么一项符合某一个条件,那么可能你要用到some方法,这个方法的返回值是一个布尔值。
var arr = [1, 2, 3, 4];
var isTrue = arr.some((item, idx) => {
return item % 2 === 0;
})
some方法和filter方法,看起来都是是否符合某个条件,但是不一样的是,filter方法会把符合条件的每一项push到一个新的数组,并且返回。而some方法只要符合条件,我就返回一个true就行了。
如果你想确保你的数组是否每一项都符合某一个条件,可能你要用到any方法:
var arr = [1, 2, 3, 4];
var isTrue = arr.any((item, idx) => {
return item % 2 === 0;
})
如果你想知道一个数组中是不是包含某一项,你可以使用includes方法:
var arr = [1,2,3];
arr.includes(1);//true
如果你想知道一个数组是不是可以找到符合条件的某一项,可以使用find方法:
var arr = [1, 2, 3];
var my = arr.find((item, index) => {
return item === 2;
})
var obj = {
name: 'mapbar_front',
age: 28,
occupation: 'web fronted'
}
Object.entries(obj);//[["name","mapbar_front"], ["age", 28], ["occupation": "web fronted"]]
一般而言,通过Object.entries 对象可以转换为Map数据结构。
var obj = { name: 'mapbar_front', age: 27 };
var map = new Map(Object.entries(obj));
如果你仅仅是想要一个对象的value的集合,一般使用Object.values来解决。
var obj = {
name: 'mapbar_front',
age: 28,
occupation: 'web fronted'
}
console.log(Object.keys(obj));//["name", "age", "occupation"];
console.log(Object.values(obj));//["mapbar_front", 28, "web fronted"];
Object.getOwnPropertyNames(obj);
//["name", "age", "occupation", "sex"];
但是Object.getOwnPropertyNames方法,只能获取键名类型为string类型的属性,一般而言,属性的类型也可以是Symbol类型,这个时候就需要另外的一种获取Symbol类型的键名的方法。
var a = Symbol();
var obj = {
name: 'mapbar_front',
age: 28,
occupation: 'web fronted',
[a]: 1234,
}
Object.defineProperty(obj, 'sex', {
value: 1,
configurable: true,
enumerable: true,
writable: true
})
var symbol = Object.getOwnPropertySymbols(obj);
console.log(symbol);// [Symbol()]这样的一个数组
var names = Object.getOwnPropertyNames(obj);
console.log(names);
在遍历的时候,对于对象的属性,我们可能要判断,这个属性是自己的实例属性,还是原型上的属性,Object的API中,有这样的一些方法:
function Foo(){}
function Bar(){}
Bar.prototype = Object.create(Foo.prototype);
var bar = new Bar();
Bar.prototype.isPrototypeOf(bar);//true。 说明Bar.prototype在bar这个对象的原型链上。
Foo.prototype.isPrototypeOf(bar);//true。 说明Foo.prototype在bar这个对象的原型链上。
Object.prototype.isPrototypeOf(bar);//true。 说明Object.prototype在bar这个对象的原型链上。
有时候,我们可能还会在想,为什么一个对象的属性没有被for in遍历出来,很有可能这个对象的属性是不可枚举的,使用下面的方法进行处理:
关于原型,我们可能要对一个对象设置一个新的原型,或者想要判断一个对象是不是在另一个对象的原型链上面。
关于对象的操作,有时候你可能在想,我能不能对一个对象做一些限制,比如我不想给一个对象增加新的属性,或者我这个对象不能删除一个属性,又或者我这个对象我都不能改变它的属性值这类的操作,可能你需要知道这三个关于对象的方法:
var obj = {
name: 'mapbar_front',
age: 23
}
Object.preventExtensions(obj);//让这个对象不可以扩展
obj.name = 'mapbar';
obj.age1 = 1234;//这里这一句不起作用
console.log(obj);//{ name: 'mapbar', age: 23 }
var obj1 = {
name: 'mapbar_front',
age: 123
}
Object.seal(obj1);
delete obj1.name;
console.log(obj1);//这个obj1没有被删除
console.log(Object.isSealed(obj1));//true
var obj2 = {
name: 'mapbar_front',
age: 123
}
Object.freeze(obj2);
obj2.name = '1111';
console.log(obj2);//这个obj2没有变
console.log(Object.isFrozen(obj2));//true