首页 > 代码库 > js中的遍历

js中的遍历

对象遍历:

首先,来理解一下对象的‘可枚举属性’,对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

var obj = {foo:123};
console.log(Object.getOwnPropertyDescriptor(obj,‘foo‘));

// { value: 123,
//     writable: true,
//     enumerable: true,
//     configurable: true }

描述对象的enumerable属性,称为”可枚举性“,如果该属性为false,就表示某些操作会忽略当前属性。

然后,写一个测试对象objtest

Object.prototype.userProp = ‘userProp‘;
Object.prototype.getUserProp = function() {
    return Object.prototype.userProp;
};
// 定义一个对象,隐式地继承自 Object.prototype
var objtest = {
    name: ‘minna‘,
    age: 21,
    [Symbol(‘symbol 属性‘)]: ‘symbolProp‘,
    unEnumerable: ‘我是一个不可枚举属性‘,
    skills: [‘html‘, ‘css‘, ‘js‘],
    getSkills: function() {
        return this.skills;
    }
};
// 设置 unEnumerable 属性为不可枚举属性
Object.defineProperty(objtest, ‘unEnumerable‘, {
    enumerable: false
});

ES6 一共有5种方法可以遍历对象的属性。

1.  for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

for (let key in objtest){
    console.log(key);
     console.log(objtest.key);
    console.log(objtest[key]);
}

不要使用 for…in 来遍历数组,虽然可以遍历,但是如果为 Object.prototype 设置了可枚举属性后,也会把这些属性遍历到,比如数组的length属性,因为数组也是一种对象。

2. Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)。

console.log(Object.keys(objtest));//[ ‘name‘, ‘age‘, ‘skills‘, ‘getSkills‘ ]

3.Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)。

console.log(Object.getOwnPropertyNames(objtest));//[ ‘name‘, ‘age‘, ‘unEnumerable‘, ‘skills‘, ‘getSkills‘ ]

4.Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性。

console.log(Object.getOwnPropertySymbols(objtest));//[ Symbol(symbol 属性) ]

5.Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举。

console.log(Reflect.ownKeys(objtest));
// [ ‘name‘,
//     ‘age‘,
//     ‘unEnumerable‘,
//     ‘skills‘,
//     ‘getSkills‘,
//     Symbol(symbol 属性) ]

数组遍历:

数组实际上也是一种对象,所以也可以使用上面对象遍历的任意一个方法(但要注意尺度),另外,数组还拥有其他遍历的方法。

最基本的有for,while循环(有一个计数变量),es6又增加了for ...of ,这下就没有计数变量了

var arr  = [1,2,3,4]
for (let value of arr){
    console.log(value)
}
// 1
// 2
// 3
// 4

数组内置的遍历方法:

1:Array.prototype.forEach(): 对数组的每个元素执行一次提供的函数,但是forEach 函数有个缺陷:不能正确处理 continue(跳过本次循环)、break(中断循环)、return(返回到外层函数) 语句的逻辑

2:Array.prototype.map(): 返回一个新数组,每个元素都是回调函数返回的值;

arr.map(function (obj) {
    console.log(obj*2)
})
// 2
// 4
// 6
// 8

一些有用的数组内置的方法:

  • Array.prototype.every(callback[,thisArg]): 测试数组的各个元素是否通过了回调函数的测试,若都通过,返回 true,否则返回 false(说地本质点儿,就是如果回调函数每次返回的值都是 true 的话,则 every() 返回 true,否则为 false)
  • Array.prototype.filter(callback[,thisArg]): 返回一个新数组,数组的元素是原数组中通过测试的元素(就是回调函数返回 true 的话,对应的元素会进入新数组)
  • Array.prototype.find(callback[,thisArg]): 返回第一个通过测试的元素
  • Array.prototype.findIndex(callback[,thisArg]): 与上面函数类似,只不过这个是返回索引
  • Array.prototype.some(callback[,thisArg]): 类似 find() ,只不过它不返回元素,只返回一个布尔值。只要找到一个通过测试的,就返回 true
  • Array.prototype.reduceRight(callback[, initialValue]): 用法和上面的函数一样,只不过遍历方向正好相反

    上面这些函数的共性

  • 都是通过每次的回调函数的返回值进行逻辑操作或判断的
  • 回调函数都可以写成更简洁的箭头函数(推荐)
  • 都可以通过形如 Array.prototype.map.call(str,callback) 的方式来操作字符串

js中的遍历