JavaScript对象遍历

弁言

遍历对象是寻常工作中很罕见的一个操纵,几乎是一样平常操纵,然则遍历对象真的是一件很轻易的事变么,明显不是的。

经常运用的体式格局

for…in

for (variable in object) {...}

这个是一个很罕见的用法,置信每一个人随手都能够写出来。然则这里须要重要的是一段这个遍历的定义

for…in语句以恣意递次遍历一个对象自有的、继续的、可罗列的、非Symbol的属性。关于每一个差别的属性,语句都邑被实行。

一个一个词抠吧。

对象自有的

假如一个key是对象自有的那末肯定能够用obj.hasOwnProperty(prop)的返回值来推断

继续的

这个也很好明白,比方下面的例子

var parent = {a: 1};

function child() {
  this.b = 'b';
}

child.prototype = parent;

var obj = new child();

此时因为obj的原型链继续了parent,所以实在obj是有a属性的。换句话说for in会遍历对象原型链上的属性

可罗列的

什么是可罗列的细致的能够看一下这个链接
起首对象的属性分为两种,数据属性如a[‘b’]=1,这个就是数据属性,另一种就是接见器属性,也就是我们用的getter。
这两种属性都有一个特性的[[Enumerable]],这个布尔值代表了这个属性是不是能够被罗列。假如一个对象的属性被设定为不可罗列,那末for in并不能够遍历到。可罗列性能够用propertyIsEnumerable来推断。

非Symbol

Symbol是什么这里不睁开说了不熟悉的发起看一下es6 symbol
symbol能够被用作给某个对象做私有属性,而假如属性值是symbol范例的那末for in也是没法遍历的。

小结

综上能够明白的晓得究竟对象的哪些属性能够用for in去遍历出来了,坑点在基本和可罗列。数组遍历我们会天然的去用for in,然则人人是不是斟酌过,数组也是一个对象,为何我们再用for in的时刻不会把数组的长度,length作为一个属性遍历到呢,缘由也就是length属性实际上是一个不可罗列属性

Object.keys()

Object.keys() 要领会返回一个由一个给定对象的本身可罗列属性构成的数组,数组中属性名的分列递次和运用 for…in 轮回遍历该对象时返回的递次一致。

注重点这里和for in有一个很大的区分,就是这个返回的是对象本身可罗列属性构成的数组,不包含继续

var parent = {a: 1};

function child() {
  this.b = 'b';
}

child.prototype = parent;

var obj = new child();
Object.keys(obj);  //['b']

Object.getOwnPropertyNames(obj)与Object.getOwnPropertySymbols(obj)

getOwnPropertyNames要领返回一个由指定对象的一切本身属性的属性名(包含不可罗列属性但不包含Symbol值作为称号的属性)构成的数组。
getOwnPropertySymbols要领返回一个给定对象本身的一切 Symbol 属性的数组。
关键词,一切的,本身的。这两个要领不受是不是可罗列属性的限定,而且是只返回本身的,所以Object.getOwnPropertyNames的返回值肯定是包含了Object.keys的返回值

Reflect.ownKeys(obj)

Reflect.ownKeys 要领返回一个由目的对象本身的属性键构成的数组。它的返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。

for…of

接下来说说另一种遍历的计划。for of 与for in 差别的就是for of是在可迭代对象(包含 Array,Map,Set,String,TypedArray,arguments 对象等等)上建立一个迭代轮回,挪用自定义迭代钩子,并为每一个差别属性的值实行语句。下面照样进入抠关键词的阶段

可迭代对象

什么是可迭代对象?遵照有可迭代协定的对象成为可迭代对象,用人话说就是一个对象假如有[Symbol.iterator],那末他就是可迭代对象。Symbol.iterator是es6供应了 1个内置的 Symbol 值。
iterator简单说就是一个有一个next函数,这个函数实行的返回值肯定是一个对象,对象有两个属性done标记迭代是不是完毕,value标记此次迭代的效果值。

如何用for…of遍历对象

综上所述也就是说给你的要遍历的对象增添一个Symbol.iterator就能够了

拓展运算符

除了上面说的还想再补充一种遍历的场景,对象的拓展运算符,那末对象的拓展运算符究竟是有哪些属性能够被赋值。
本身的,可罗列的。能够看两个例子

var obj = {}
Object.defineProperty(obj, 'key', {
    enumerable: false,
      configurable: true,
      writable: true,
  value: "a"
});
b = {...obj};
console.log(b); //{}

能够看到不可罗列属性在解构赋值中是不可被赋值的。

var parent = {a: 1};

function child() {
  this.b = 'b';
}

child.prototype = parent;

var obj = new child();
var b = {...obj};  
console.log(b);//{b: 'b'}

能够看到继续的属性在解构赋值中是不可被赋值的。

总结

对象的遍历要领许多,然则要根据详细对象属性的特性和运用场景,另有兼容性来挑选最适合的遍历计划。

    原文作者:求实亭下
    原文地址: https://segmentfault.com/a/1190000019266624
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞