GithubHelp home page GithubHelp logo

Comments (11)

luohong123 avatar luohong123 commented on May 29, 2024 5

可迭代对象的特点

image

代码如下:

function makeIterator(array){
    var nextIndex = 0;
    return {
       next: function(){
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
}
// 使用 next 方法依次访问对象中的键值
var it = makeIterator(['step', 'by','step']);
console.log(it.next().value); // 'step'
console.log(it.next().value); // 'by'
console.log(it.next().value); // 'step'
console.log(it.next().value);  // undefined
console.log(it.next().done); // true

参考文章

from step-by-step.

AILINGANGEL avatar AILINGANGEL commented on May 29, 2024 1

可迭代对象可以采用统一的接口对对象进行遍历,比如for...of, 而不需要关注对象内部的具体结构。在JS中可迭代的对象需要返回一个包含next方法的对象,next方法再返回一个包含value和done两个属性的对象。value是指每次迭代的值,而done用来表示是否已经迭代完毕。

给一个对象定义一个迭代器,使之可以采用for...of来迭代属性所对应的值.

let obj = {
    name: 'age',
    age: 20,
    sex: 'female',
    [Symbol.iterator]() {
        var self = this;
        var i = 0;
        var keys = Object.keys(this);
        return {
            next() {
                if (i < keys.length) {
                    return {
                        value: self[keys[i++]],
                        done: false
                    }
                } else {
                    return {
                        value: undefined,
                        done: true
                    }
                }
            }
        }
    }
}
for (let item of obj) {
    console.log(item); // age 20 female
}

from step-by-step.

shenanheng avatar shenanheng commented on May 29, 2024

数据结构:
a:Array
b:Object
c:Map
d:Set
可迭代的对象 => 数据结构只要部署了迭代器的接口
在原生的数据类型中(有Symbol.iterator)

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象
    Object可以自己写Symbol.iterator的函数

特点:
a:获取value与done
b:next()方法可以指向下一个指针

from step-by-step.

riluocanyang avatar riluocanyang commented on May 29, 2024

可迭代对象有什么特点?

数组常用的可迭代方法有:

  1. every()
  2. some()
  3. filter()
  4. forEach()
  5. map()
  6. for...of
    ...

对象常用的可迭代方法有:

  1. Object.keys()
  2. Object.values()
  3. Object.entries()
  4. for... in
  5. for... of
    ...

它们的特点:

迭代器(Iterator):其内部都返回了next()方法,每次调用next方法都返回了一个对象,这个对象有两个属性,分别是value和done,value表示下一个将要返回的值,如果没有更多数据,done值为true。
迭代对象(Iterable):具有迭代器的属性,也就是能够通过一个函数返回一个迭代器。

from step-by-step.

woyiweita avatar woyiweita commented on May 29, 2024

可迭代对象可通过 for...of 进行循环。

模拟迭代器:

    function makeIterator(arr) {
        var nextIndex = 0;
        return {
            next: function () {
                return nextIndex < arr.length ? {
                    done: false,
                    value: arr[nextIndex++]
                } : {
                    done: true
                };
            }
        }
    }

    var it = makeIterator(['a', 'b', 1, 6, NaN, null, undefined]);
    var res;
    do {
        res = it.next();
        console.info(res.value);
    } while (!res.done);

为了实现可迭代,一个对象必须实现 iterator 方法,这意味着这个对象(或其原型链中的一个对象)必须具有带 Symbol.iterator 键的属性

判断当前对象是否为可迭代对象,检测该对象是否具备 Symbol.iterator 属性。

    // 以数组为例
    Array.prototype.hasOwnProperty(Symbol.iterator); // => true

可通过检测当前对象是否具有Symbol.iterator属性来判断当前对象是否为可迭代对象。Symbol.iterator 是一个函数,所以通过typeof来检测返回值,如果返回值为'function'则为可迭代对象,如果返回值为'undefined'则为不可迭代对象。

    typeof [][Symbol.iterator]; // => 'function'
    typeof {}[Symbol.iterator]; // => 'undefined'
    typeof new Set()[Symbol.iterator]; // => 'function'
    typeof new Map()[Symbol.iterator]; // => 'function'
    typeof ''[Symbol.iterator]; // => 'function'
    var list = document.querySelectorAll('p'); // 获取dom节点
    typeof list[Symbol.iterator]; // => 'function'
    typeof new Int8Array()[Symbol.iterator]  // => 'function'
    (function(){
        typeof arguments[Symbol.iterator]; // => 'function'
    })();

原生具备 Iterator 接口的数据结构如下。

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

数组如何使用.next() 方法:

    var arr = [1,2,3];
    var si = arr[Symbol.iterator]();
    si.next(); //=> {value: 1, done: false}
    si.next(); //=> {value: 2, done: false}
    si.next(); //=> {value: 3, done: false}
    si.next(); //=> {value: undefined, done: true}

如何实现一个自定义的可迭代对象:

    var myIterator = {};
    myIterator[Symbol.iterator] = function* () {
        yield 'Bryan';
        yield 'programmer';
        yield 'bachelordom';
    }
    for (let val of myIterator) {
        console.info(val);
    }
    // Bryan
    // programmer
    // bachelordom

总结

可迭代对象的特点:

  • 可使用 for...of 进行循环;
  • 对象或者原型链当中具有 Symbol.interator 属性;
  • 可通过迭代器访问并跟踪该序列中的当前位置。(迭代器提供next()方法,返回对象包含done和value方法)

from step-by-step.

jodiezhang avatar jodiezhang commented on May 29, 2024

首先了解遍历器的概念(iterator)
它是一种接口,为各种不同的数据结构提供统一的访问机制
任何数据结构,只要部署了Iterator接口,就可以完成遍历操作。
Iterator的作用有三个:
一个是为各种数据提供一个统一的,简便的访问接口
二是使得数据结构的成员能够按照某种次序排列
三是ES6创造了一种新的遍历命令,for...of循环,Iterator接口主要供for...of消费

Iterator的遍历过程如下:
1.创建一个指针对象,指向当前数据结构的起始位置。
2.第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员
3.第二次调用指针对象的next方法,指针就指向数据结构的第二个成员
4.不断调用指针对象的next方法,直到它指向数据结构的结束位置
每次调用next方法都会返回数据结构的当前成员信息。具体来说,就是返回一个包含value和done两个属性的对象。其中value是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

var it=makeIterator(['a','b']);
it.next()
it.next()
it.next()

function makeIterator(array) {
var nextIndex=0;
return {
next: function(){
return nextIndex<array.length?
          {value:array[nextIndex++],done:false}:
          {value:undefined,done:true};
}
}
}

数据结构只要部署了Iterator接口,我们就称这种数据结构为可遍历的或者可迭代的。
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说一个数据结构只要具有Symbol.iterator属性,就可以认为是可遍历的(iterable)。
原生具备Iterator接口的数据结构如下:

Array
Map
Set
String
TypeArray
函数的arguments对象
NodeList对象

为一个对象添加Iterator 接口

let obj={
data: ['hello','world'],
[Symbol.iterator](){
const self=this;
let index=0;
return {
next(){
if(index<self.data.length){
return {
value:self.data[index++],
data: false
}
}else{
return {value:undefined,done:true}
}
}
}
}
}

Symbol.iterator方法最简单的实现还是用Generator函数

let obj={
*[Symbol.iterator](){
yield 'hello';
yield 'world';
}
}
for(let x of obj){
console.log(x);
}

引用:ES6标准入门-阮一峰

from step-by-step.

chongyangwang avatar chongyangwang commented on May 29, 2024

数组的可迭代方法:

  1. array.foreach
  2. array.some
  3. array.every
  4. array.map
  5. array.filter

对象的可迭代方法

  1. object.keys()
    2.object.values()
  2. for of
  3. for in

实现 copy form https://github.com/luohong123

function makeIterator(array){
    var nextIndex = 0;
    return {
       next: function(){
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
}
// 使用 next 方法依次访问对象中的键值
var it = makeIterator(['step', 'by','step']);
console.log(it.next().value); // 'step'
console.log(it.next().value); // 'by'
console.log(it.next().value); // 'step'
console.log(it.next().value);  // undefined
console.log(it.next().done); // true

from step-by-step.

yelin1994 avatar yelin1994 commented on May 29, 2024

可迭代对象有什么特点

遍历器(Interator)

定义: 他是一种接口, 为各种不同的数据结构提供统一的访问机制。 任何数据只要部署interator接口,就可以完成遍历操作。其主要供for...of 消费。(w3c定义)

遍历过程:

  • 创建一个指针对象,指向当前数据结构的起始位置。
  • 不断调用指针对象的next方法,直到他指向数据结构结束的位置。
function createIterator (items) {
     var i = 0
    return {
         next: function () {
             var done = (i >= items.length)
             var value = !done ? items[i++]: 'undefined'
             return {
                 done: done,
                 value: value
             }
         }
    }
}
var iterator = createIterator([1,2, 3])
模拟next返回的例子

原生具备可迭代(遍历的对象)(这边以for...of 区分):

  • 数组
  • 某些类似数组的东西 arguments, nodelist, String 等
function foo () { 
 for (var i of arguments) { console.log(i) } 
}
foo(1, 2, 3, 4)
  • es6 新增的Set, Map 结构
  • 生成器也可以遍历
function *aGenerator () {
    yield  1
    yield  2
    yield 3
}
var agen = aGenerator()
for (var i of agen) {
    console.log(i)
}
  • 对象不能可遍历,但可通过部署Symbol.interator实现
Object.prototype[Symbol.iterator] = function* () {
    for (const key in this) {
        yield [key , this[key]]
    }
}

var a = {
    name: 'Jimmy',
    age: 18,
    job: 'actor'
}
for (var i of a) {
    console.log(i)
}

或者也可采用

Object.prototype[Symbol.iterator] = function () {
    var i = 0
    const names = Object.entries(this)
    return {
        next: function () {
            var done = (i >= names.length)
            var value = !done ? names[i++]: undefined
            return {
                done: done,
                value: value
            }
        }
    }
}
var a = {
    name: 'Jimmy',
    age: 18,
    job: 'actor'
}
for (var i of a) {
    console.log(i)
}

from step-by-step.

YvetteLau avatar YvetteLau commented on May 29, 2024

ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,换个角度,也可以认为,一个数据结构只要具有 Symbol.iterator 属性(Symbol.iterator 方法对应的是遍历器生成函数,返回的是一个遍历器对象),那么就可以其认为是可迭代的。

可迭代对象的特点

  • 具有 Symbol.iterator 属性,Symbol.iterator() 返回的是一个遍历器对象
  • 可以使用 for ... of 进行循环
let arry = [1, 2, 3, 4];
let iter = arry[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 }

原生具有 Iterator 接口的数据结构:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

自定义一个可迭代对象

上面我们说,一个对象只有具有正确的 Symbol.iterator 属性,那么其就是可迭代的,因此,我们可以通过给对象新增 Symbol.iterator 使其可迭代。

let obj = {
    name: "Yvette",
    age: 18,
    job: 'engineer',
    *[Symbol.iterator]() {
        const self = this;
        const keys = Object.keys(self);
        for (let index = 0; index < keys.length; index++) {
            yield self[keys[index]];//yield表达式仅能使用在 Generator 函数中
        }
    }
};

for (var key of obj) {
    console.log(key); //Yvette 18 engineer
}

from step-by-step.

KRISACHAN avatar KRISACHAN commented on May 29, 2024

可迭代对象的特点就是可迭代。。。
一个具有 @@iterator 方法的对象,当然这个可以通过 Symbol.iterator 去生成

from step-by-step.

MissNanLan avatar MissNanLan commented on May 29, 2024

遍历器(Iterator)它是一种借口,为各种不同的数据结构提供统一的访问机制。 任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
它的作用有三个:
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据接口的成员能够按照某种次序排列;
三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要提供for...of消费

遍历过程,创建一个指针对象,调用指针的next方法,每调用依次next方法,就会返回valuedone两个属性对象,value属性是当前成员的值,done属性是一个布尔值,表示循环可以结束

var it = makeIterator(['a','b']);
console.log(it.next());
console.log(it.next());
console.log(it.next());

function makeIterator(array){
  var nextIndex = 0;
  return {
    next: function(){
      return nextIndex < array.length ?
        { value: array[nextIndex++],done: false }:
        {value:undefined,done: true}
    }
  }
}

具有原生Iterator接口的数据结构

Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象

凡是部署了Symbol.iterator属性,都称之为部署了遍历器接口,返回一个遍历器对象;对于原生部署了Iterator接口,for...of会自动去遍历,如果没有的话(比如对象),都需要自己在Symbol.iterator属性上面部署

总结: 一个数据结构(数组、Map、Set,某些类似数组的对象——比如arguments对象,DOM NodeList对象,Generator对象,字符串等),才可以被for...of循环遍历。 换句话说就是for...of 循环内部调用的是数据结构Symbol.iterator方法

[更多请参考参考阮一峰](http://es6.ruanyifeng.com/#docs/iterator

from step-by-step.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.