for...in

  1. 以任意顺序迭代一个对象的可枚举属性,包括继承的可枚举属性。(包括继承属性)(不包括Symbol)
  2. 可以迭代数组
  3. 遍历顺序

    先遍历出(非负)整数属性(integer properties,按照升序),
    然后其他属性按照创建时候的顺序遍历出来
let obj = {
    "49": "Germany",
    "41": "Switzerland",
    "44": "Great Britain",
    "1": "USA",
    name:"ljy",
    "-5":"jeu",
    "type":"lily",
    "2.34":"pai",
    "-6":"dhoe"
  };

  for(let key in obj) {
    console.log(key); 
  }

结果为:

1
41
44
49
name
-5
type
2.**34**
 -6

原因,ECMAScript规范中定义了 「数字属性应该按照索引值⼤⼩升序排列,字符 串属性根据创建时的顺序升序排列。」在这⾥我们把对象中的数字属性称为 「排序属性」

这里有篇详细说明的文章

> 不推荐用for-in遍历数组

* for-in是为遍历对象属性而构建的,可以遍历数组是因为数组也是对象
* 顺序
* for-in 遍历所得的key都是字符串类型,对应数组'0','1',...
* 如果数组有添加自定义可枚举属性,也会遍历出来


for-of

  1. for-of是ES6新增的遍历器(Iterator)方法.
  2. 只要该对象有Symbol.iterator属性,就被视为具有 iterator 接口,就可以用
  3. Array,Map,Set,String,TypedArray,arguments 对象,NodeList对象 都可以遍历
  4. 普通对象Object不支持,需要先实现Symbol.iterator方法
  5. for-of 遍历的顺序是按照各个成员被添加进数据结构的顺序
  6. for-of 遍历数组获取到的是键值
默认迭代器不包括继承属性,除非自定义迭代器
var a = [1,'10',0,'s','']
for(let key of a) {
    console.log(key); 
  }
1
10
0
s

Object.keys

Object.keys、Object.values和Object.entries
  1. 遍历对象自身的(不含继承的)所有可枚举属性(不包括Symbol)
  2. 顺序同for-in
  3. 返回同样是字符串
let a = [1,1,2,3]
console.log(Object.keys(a))

// 结果
['0', '1', '2', '3']

题外,数组length属性是不可枚举的
Object.getOwnPropertyDescriptor(a,'length')
// 结果
{
    configurable: false,
     enumerable: false,
     value: 4,
     writable: true
}

肥皂泡
382 声望6 粉丝

码农