美文网首页
js通过迭代器对象用for..of遍历对象的值

js通过迭代器对象用for..of遍历对象的值

作者: 景阳冈大虫在此 | 来源:发表于2020-05-13 10:47 被阅读0次

我们知道for..of循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有返回值。
对于一个数组,因为数组有内置的@@iterator,所以for..of可以直接用在数组上,利用这个@@iterator来手动遍历数组如下:

var myArray = [1,2,3];
var it = myArray[Symbol.iterator]();

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

@@iterator本身并不是一个迭代器对象,而是一个返回迭代器对象的函数——这点非常精妙并且非常重要。

Symbol

了解@@iterator是个什么东西,首先要了解Symbol类型。它是ES6新增加的一种基本数据类型。

数据类型 “symbol” 是一种原始数据类型,该类型的性质在于这个类型的值可以用来创建匿名的对象属性。
该数据类型通常被用作一个对象属性的键值——当你想让它是私有的时候。例如,symbol 类型的键存在于各种内置的 JavaScript 对象中。

特别地:

Symbol 类具有一些静态属性,对于匿名命名来说,这带有一点讽刺意味。这类属性只有几个; 它们是所谓的“众所周知”的 symbol。 它们是在某些内置对象中找到的某些特定方法属性的 symbol。 暴露出这些 symbol 使得可以直接访问这些行为;这样的访问可能是有用的,例如在定义自定义类的时候。
普遍的 symbol 的例子有:“Symbol.iterator”用于类似数组的对象,“Symbol.search”用于字符串对象。

用法如下:

const foo = Symbol()
const bar = Symbol()
let obj = {}
obj[foo] = "foo"
obj[bar] = "bar"
JSON.stringify(obj) // {}
Object.keys(obj) // []
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [ foo, bar ]

defineProperty

在创建普通属性时属性描述符会使用默认值,我们也可以使用Object.defineProperty(..)来添加一个新属性或者修改一个已有属性(如果它是configurable)并对特性进行设置。
对于一个普通对象属性来说,除了value之外,还包含另外三个特性:writable(可写)、enumerable(可枚举)和configurable(可配置)
举例来说:

var myObject = {};

Object.defineProperty( myObject, "a", {
    value: 2,
    writable: true, 
    configurable: true, 
    enumerable: true
} ); 

myObject.a; // 2

遍历对象

通过上文的预备知识,我们可以这样去定义@@iterator以便遍历对象

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

相关文章

  • js通过迭代器对象用for..of遍历对象的值

    我们知道for..of循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有...

  • 迭代器和生成器

    for..of 语句for..of会遍历可迭代的对象,调用对象上的Symbol.iterator方法。 下面是在数...

  • (5) python 迭代器和生成器

    (一)迭代器 迭代器是一种对象,该对象包含值的可计数数字。迭代器是可迭代的对象,这意味着您可以遍历所有值。 从技术...

  • 闭包的应用

    闭包的应用(继续昨天) for..of循环的底层实现 - 迭代器(Iterator) ​ 某个对象或者该对象的...

  • 设计模式——迭代器模式

    什么是迭代器模式 用迭代器来封装集合对象的遍历细节,使调用者能够通过统一的接口来实现对集合的遍历。 迭代器也给集合...

  • 十一、遍历对象,遍历数组

    1、ES6的for..of遍历,不能遍历对象 2、遍历对象 对象的方法 一、Object.assign 循环 一、...

  • for...of与for...in的区别

    for...in(遍历对象) 用于遍历对象的key值 for...of (遍历数组) 用于遍历有内置迭代...

  • java设计模式16(迭代器模式)

    迭代器用于对一个聚合对象进行遍历。通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,...

  • 迭代理解

    对于给定的对象,如果可以通过 for 循环来遍历整个对象。 这种遍历我们称为迭代。 这类对象我们称为可迭代对象。 ...

  • python入门(三)迭代器和生成器

    迭代器 迭代器可以记住遍历位置的对象 list、tuple、dict都只是可以迭代的对象,不是迭代器,所以要创建一...

网友评论

      本文标题:js通过迭代器对象用for..of遍历对象的值

      本文链接:https://www.haomeiwen.com/subject/rneinhtx.html