亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 基础

  • 手写代码

    • 手写类型转换
    • 手写累加、累乘函数
    • 手写new
    • 手写深拷贝
    • 手写Object.create
    • 手写继承
    • 手写extends
    • 手写instanceof
    • 手写call、apply、bind
    • 手写jsonp
    • 手写getQueryString
    • 手写setInterval
    • 手写防抖与节流
    • 手写对象属性值迭代器
      • for in 和 for of 的区别
      • 哪些数据结构部署了 Symbol.iteratoer属性?
    • 手写分时函数
    • 手写事件委托
    • 手写图片懒加载
    • 手写原生Ajax请求
    • 手写AOP装饰函数
    • 手写柯里函数
    • 手写数组扁平化flat
    • 手写数组去重
    • 手写eventEmit类
    • 手写Vue数据响应式
    • 手写Vue nextTick
    • 手写Promise
  • JS底层深入

  • CSS

  • 基础
  • 手写代码
0zcl
2021-06-18
目录

手写对象属性值迭代器

# for in 和 for of 的区别

  1. for ... in 循环返回的值都是数据结构的 键值名
  2. for ... of 循环用来获取一对键值对中的值

ES6规定,一个数据结构只要部署了 <code>Symbol.iterator</code> 属性, 就被视为具有 iterator 接口, 就可以使用 for of循环。

# 哪些数据结构部署了 Symbol.iteratoer属性?

  • 数组
  • Map
  • Set
  • arguments类数组
  • NodeList对象。即获取的dom列表集合
const container = document.getElementsByTagName('li')
for (let node of container) {
    console.log(node)
}
1
2
3
4

注意

输出打印题

// 题一
const arr = ['a', 'b']
arr.name = 'qiqingfu'
for (let i in arr) {
  console.log(i)
}

// 题二
const obj = { a: 1, b: 2, c: 3 }
for (let i of obj) {
  console.log(i)
}

// 答
// 题一
0
1
name

// 题二
会爆错。因为对象没有 Symbol.iterator 属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

注意

自定义对象属性值迭代器,使之能使用for of循环遍历对象属性的值

答:

function iterator(obj) {
  Object.defineProperty(obj, Symbol.iterator, {
    value: function() {
      let index = 0
      // console.log('obj', obj, this)
      const keyList = Object.keys(obj)
      return {
        next: function() {
          return {
            done:  index >= keyList.length,
            value: obj[keyList[index++]]
          }
        }
      }
    }
  })
}
// 测试
var obj = {
  name: 'AAA',
  age: 23,
  address: '广州'
}
iterator(obj)
for (const val of obj) {
  console.log(`属性值为:${val}`);
}
// 属性值为:AAA
// 属性值为:23
// 属性值为:广州
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

iterator(遍历器) 的遍历过程

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用指针对象的<code>next</code>方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置

每一次调用next方法, 都会返回一个包含<code>value</code>和<code>done</code>两个属性的对象。value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();

iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
1
2
3
4
5
6
7

执行对象的Symbol.iterator函数会返回一个对象,对象有next方法属性,执行next函数,会返回 { value: xx, done: xx }

知识点:需要熟练掌握Object.defineProperty, 及深入理解iterator。🍭

参考: 百度前端面试题:for in 和 for of的区别详解以及为for in的输出顺序 (opens new window)

编辑 (opens new window)
上次更新: 2025/07/17, 07:17:44
手写防抖与节流
手写分时函数

← 手写防抖与节流 手写分时函数→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式