for-in和for-of区别

for-in和for-of区别

先说说结论

  • for-in适合遍历对象属性,for-of适合遍历数组
  • for-in循环出的是key值,for-of循环出的是value
  • for-in可以遍历可枚举的属性,for-of遍历的是可迭代的
  • for-of不能直接遍历普通的对象,需要通过Object.keys()搭配使用

for-in循环

最早期遍历数组的方式就是一层for循环遍历数组下标:

let a=[1,2,3,4];
for(let i=0;i<a.length;i++){
    console.log(a[i]);
}

到后面ES5发布之后,又可以通过forEach来遍历数组,但是使用forEach的缺点就是不能中断

既然想到通过for来循环,就会想到for-in:

let a=[1,2,3,4];
a.name="zhangsan"
console.log(a)
for(let index in a){
    console.log(index)
}

但是这样会出现以下几个问题:

  • 赋值给index并不是一个数字,而是一个字符串
  • for-in除了遍历数组中的元素之外,还回去遍历自定义的属性,甚至数组原型链上的属性都能访问到。
  • for-in可会不会按照数组的顺序遍历数组。

for-of循环

for-of方法修复了for-in循环的缺点,并且和forEach不同的是他还能通过breakreturn终止循环,同时 除了数组之外,还支持像Set、Map、类数组对象等数据结构, 注意:for-of循环不支持普通对象,但是如果你想迭代一个对象的属性,可以使用for-in循环或者内建的Object.keys()方法

for-of循环原理

在说原理之前先说说迭代器,那什么是迭代器呢?

所谓迭代器就是一个拥有next()方法的对象,每次调用next()方法都会返回一个结果,该结果有两个属性,一个是value表示当前获取的值,第二个是done表示遍历是否结束,下面手动实现一个迭代器:

function createIterator(items){
  function addIterator(items){
    let i = 0
    let done = false
    return {  
      next() {
        done = i >= items.length
        return {
          value: items[i++],
          done
        }
      }
    }
  }
  let iterator =[];
  //给iterator添加一个Symbol.iterator属性,只有这样这种数据才是"可遍历的"。
  iterator[Symbol.iterator] = ()=> addIterator(items)
  return iterator
}

let a=[1,2,3,4];
let iter=createIterator(a)[Symbol.iterator]();
console.log(iter.next())//{ value: 1, done: false }
console.log(iter.next())//{ value: 2, done: false }
console.log(iter.next())//{ value: 3, done: false }
console.log(iter.next())//{ value: 4, done: false }
console.log(iter.next())//{ value: undefined, done: true }

这其实也就是for-of的原理,他其实帮我们做的就是获取数据的迭代器对象,然后一个一个遍历。

那这里就有一个疑问了,我们平时定义的数组没给他添加 Symbol.iterator 属性啊,其实是数组默认 部署了Symbol.iterator 属性。

下面就模拟实现下for-of:

function forOf(obj, cb) {
    let iterable, result;

    if (typeof obj[Symbol.iterator] !== "function")
        throw new TypeError(result + " is not iterable");
    if (typeof cb !== "function") throw new TypeError("cb must be callable");

    iterable = obj[Symbol.iterator]();

    result = iterable.next();
    while (!result.done) {
        cb(result.value);
        result = iterable.next();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容