in和of都是在js中经常用到的遍历方法,今天就来了解一下其区别以及使用场景吧。

1. 首先明确基本使用方法:

for(let key in objs){
    ...
}
for(let obj of arrs){
    ...
}

从上述代码已经能看出来一定的使用场景了,简单来说,in操作符遍历的是对象的可枚举属性,主要用来遍历对象的键,而of是用来遍历值,主要用于对于数组内元素的遍历。

2. in

in操作符还是比较好理解的,除了遍历之外,in操作符还可以直接判断某个属性是否存在于该对象例如key in obj //true等,当作为遍历使用时,则只会遍历对象中属性描述符为可枚举的对象,与in类似的有obj.hasOwnProperty(key),其区别主要是in操作符会查找原型链,而后者不会,如下:

let foo = function (){
    this.a = 'a'
}

foo.prototype.bar = 'bar'

let fooObj = new foo();

for(let k in fooObj){
    console.log(k)    \\ a bar
}

console.log(fooObj.hasOwnProperty('bar'))    //false

这里in操作符不适用于数组的原因是当遍历数组的时候不止会返回数组下标,还会返回Array的一些其他可枚举属性,有时候这是意料之外的。

3. of

对于for...of...来说本质上是向被访问对象请求迭代器方法,并且使用iterator.next()来遍历数组的,下面可以使用内置的iterator来演示一下如何手动遍历数组:

let arr = [1, 2, 3];
let it = arr[Symbol.iterator]();

console.log(it.next()); //{ value: 1, done: false }
console.log(it.next()); //{ value: 2, done: false }
console.log(it.next()); //{ value: 3, done: false }
console.log(it.next()); //{ value: undefined, done: true }

与此类似,可以自己构造对于对象的值的遍历,这里直接摘抄代码吧:

var myObject = {
    a: 2,
    b: 3
};

Object.defineProperty( myObject, Symbol.iterator, {
    enumerable: false,
    writable: false,
    configurable: true,
    value: function() {
        var o = this;
        var idx = 0;
        var ks = Object.keys( o );
        return {
            next: function() {
                return {
                    value: o[ks[idx++]],
                    done: (idx > ks.length)
                };
            }
        };
    }
} );

// 手动迭代 `myObject`
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { value:undefined, done:true }

// 用 `for..of` 迭代 `myObject`
for (var v of myObject) {
    console.log( v );
}
// 2
// 3

一句话总结,对象用in,数组用of

3人点赞