目次
はじめに
1 正题
1.1 基本行为
1.2 简单实现
1.3 return & throw
2 原生支持
2.1 默认持有遍历器
1.1 基本動作
1.2 簡単な実装
2.1 デフォルトでトラバーサーを保持します
2.2 默认调用遍历器
ホームページ ウェブフロントエンド jsチュートリアル イテレータは、データ コレクションにアクセスするための統一インターフェイス メソッドです。

イテレータは、データ コレクションにアクセスするための統一インターフェイス メソッドです。

Jul 20, 2018 am 10:15 AM
es6 iterator javascript フロントエンド インターフェース

この記事では、Iterator によるデータ収集にアクセスするための統一インターフェイス方法を紹介します。必要な場合は、それを参照してください。

はじめに

Traverser Iterator は、データ コレクションにアクセスするために ES6 によって提供される統合インターフェイスです。トラバーサー インターフェイスが内部に展開されているデータ コレクションの場合、ユーザーは同じ方法で対応するデータ構造を取得できます。最新バージョンの Chrome ブラウザを使用している場合は、私たちがよく知っているミス・アレイが、彼女の心に届く別の道を静かに開いたことを知っておく必要があります。 Iterator是ES6为访问数据集合提供的统一接口。任何内部部署了遍历器接口的数据集合,对于用户来说,都可以使用相同方式获取到相应的数据结构。如果使用的是最新版Chrome浏览器,那么你要知道——我们所熟悉的数组小姐,已悄悄的打开了另一扇可抵达她心扉的小径。

1 正题

某个数据集合部署了Iterator接口,是指其Symbol.iterator属性指向一个能返回Iterator接口的函数。任何默认使用遍历器访问数据集合的方法,都会调用此属性以得到遍历器对象,再按照设定的顺序依次访问该数据结构的成员(关于Symbol.iterator请看最后一节的延伸阅读)。比如原生数组的遍历器为[][Symbol.iterator],也可以直接通过其构造函数的原型获取Array.prototype[Symbol.iterator]

1.1 基本行为

调用Iterator接口会返回一个新的遍历器对象(指针对象)。  
对象中必然有next方法,用于访问下一个数据成员。指针初始时指向当前数据结构的起始位置。

第一次调用对象的next方法,指针指向数据结构的第一个成员。  
第二次调用对象的next方法,指针指向数据结构的第二个成员。  
不断的调用对象的next方法,直到它指向数据结构的结束位置。

每次调用next方法,都会返回相同的数据结构:{ value, done }。  
其中value表示当前指向成员的值,没有则为undefined。  
其中done是一个布尔值,表示遍历是否结束,结束为true,否则false

遍历器接口的标准十分简洁,不提供诸如:操作内部指针、判断是否有值等等方法。只需要一直不断的调用next方法,当donefalse时获取当时的valuedonetrue时停止即可。第一次接触遍历器的行为模式是在2016的冬天,那时底蕴不够鸡毛也没长全,理解不了简洁性的适用和强大。直到现在——在即将打包被迫离开公司的前夕才蓦然的醒觉。多么痛的领悟啊。

let iterator = [1, 2, 3][Symbol.iterator]();

console.log( iterator.next() ); // {value: 1, done: false}
console.log( iterator.next() ); // {value: 2, done: false}
console.log( iterator.next() ); // {value: 3, done: false}
console.log( iterator.next() ); // {value: undefined, done: true}
ログイン後にコピー

1.2 简单实现

面向不同的数据结构,有不同的遍历器实现方法,我们简单的实现下数组的遍历器方法。

let res = null;
let iterator = myIterator([3, 7]);

console.log( iterator.next() ); // {value: 3, done: false}
console.log( iterator.next() ); // {value: 7, done: false}
console.log( iterator.next() ); // {value: undefined, done: true}

function myIterator(array = []) {
  let index = 0;
  return {
    next() {
      return index < array.length 
        ? { value: array[index++], done: false }
        : { value: undefined, done: true };
    }
  };
}
ログイン後にコピー

1.3 return & throw

除了为遍历器对象部署next方法,还可以有returnthrow方法。其中return方法会在提前退出for of循环时(通常是因为出错,或触发了break语句)被调用。而throw方法主要是配合Generator函数使用,一般的遍历器对象用不到这个方法,所以不予介绍。

let obj = {
  [Symbol.iterator]() {
    let index = 0;
    let array = [1, 2, 3];

    return {
      next() {
        return index < array.length 
          ? { value: array[index++], done: false }
          : { value: undefined, done: true };
      },
      return() {
        console.log(&#39;Trigger return.&#39;);
        return {};
      }
    };
  }
};

for (let v of obj) {
  console.log(v); // 打印出:1, 2, 3,没触发 return 函数。
}

for (let v of obj) {
  if (v === 2) break;
  console.log(v); // 打印出:1,之后触发 return 函数。
}

for (let v of obj) {
  if (v === 3) break;
  console.log(v); // 打印出:1, 2,之后触发 return 函数。
}

for (let v of obj) {
  if (v === 4) break;
  console.log(v); // 打印出:1, 2, 3,没触发 return 函数。
}

for (let v of obj) {
  if (v === 2) throw Error(&#39;error&#39;);
  console.log(v); // 打印出:1,之后触发 return 函数,并报错停止执行。
}
ログイン後にコピー

2 原生支持

2.1 默认持有遍历器

原生默认持有遍历器接口的数据结构有:
基本类型:Array, Set, Map(四种基本数据集合:Array, Object, SetMap)。
类数组对象:arguments, NodeList, String

let iterator = &#39;123&#39;[Symbol.iterator]();

console.log( iterator.next() ); // {value: "1", done: false}
console.log( iterator.next() ); // {value: "2", done: false}
console.log( iterator.next() ); // {value: "3", done: false}
console.log( iterator.next() ); // {value: undefined, done: true}
ログイン後にコピー

遍历器与先前的遍历方法
一个数据集合拥有遍历器接口,并不意味着所有遍历它的方法都是使用此接口。实际上,只有ES6新增的几种方式和某些方法会使用,下面会有介绍。以数组来说,对其使用forfor of虽然可访问到相同的成员,但是实际的操作方式却不同。

// 改变数组默认的遍历器接口。
Array.prototype[Symbol.iterator] = function () {
  let index = 0;
  let array = this;

  console.log(&#39;Use iterator&#39;);

  return {
    next() {
      return index < array.length 
        ? { value: array[index++], done: false }
        : { value: undefined, done: true };
    }
  }
};

let arr = [1, 2];

for (let v of arr) {
  console.log(v); // 打印出 Use iterator, 1, 2。
}

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 打印出 1, 2。
}

arr.forEach(d => {
  console.log(d); // 打印出 1, 2。
});
ログイン後にコピー

对象没有默认的遍历器接口  
为什么对象没有默认的遍历器接口?这要从两方面说明。一为遍历器是种线性处理结构,对于任何非线性的数据结构,部署了遍历器接口,就等于部署一种线性转换。二是对象本来就是一个无序的集合,如果希望其有序,可以使用Map

1 メイントピック🎜🎜 特定のデータ コレクションは Iterator インターフェイスをデプロイします。これは、その Symbol.iterator 属性が を返すことができるデータ セットを指すことを意味します。イテレータ 関数。デフォルトでトラバーサーを使用してデータ コレクションにアクセスするメソッドは、このプロパティを呼び出してトラバーサー オブジェクトを取得し、設定された順序でデータ構造のメンバーにアクセスします (Symbol.iterator については最後のセクションを参照してください)。詳細については「code>」セクションを参照してください)。たとえば、ネイティブ配列のイテレータは <code>[][Symbol.iterator] です。または、そのプロトタイプから直接 Array.prototype[Symbol.iterator] を取得できます。コンストラクタ。 🎜

1.1 基本動作

🎜 Iterator インターフェイスを呼び出すと、新しいイテレータ オブジェクト (ポインタ オブジェクト) が返されます。
オブジェクトには、次のデータ メンバーにアクセスするために使用される next メソッドが必要です。ポインタは最初は現在のデータ構造の先頭を指します。 🎜🎜オブジェクトの next メソッドが初めて呼び出されるとき、ポインターはデータ構造の最初のメンバーを指します。
オブジェクトの next メソッドが 2 回目に呼び出されるとき、ポインタはデータ構造の 2 番目のメンバーを指します。
データ構造の終わりを指すまで、オブジェクトの next メソッドを繰り返し呼び出します。 🎜🎜 next メソッドが呼び出されるたびに、同じデータ構造、{ value, none } が返されます。
ここで、value は現在メンバーを指している値を表します。そうでない場合は、未定義となります。
done はブール値で、終了が true かどうかを示し、それ以外の場合は false です。 🎜🎜トラバーサーインターフェースの規格は非常にシンプルで、内部ポインターの操作や値の有無の判定などのメソッドは提供されていません。 next メソッドを呼び出し続け、donefalse になったら、現在の value を取得します。完了したら停止はtrueです。私がトラバーサーの行動パターンに初めて触れたのは、2016 年の冬でした。当時、私にはシンプルさの応用可能性と威力を理解するための十分な知識がありませんでした。突然目が覚めたのは、今まさに荷物をまとめて会社を去らなければならない直前のことだった。なんという痛ましい認識だろう。 🎜
let obj = {
  0: 'a',
  1: 'b',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};

let iterator = obj[Symbol.iterator]();
console.log( iterator.next() ); // {value: "a", done: false}
console.log( iterator.next() ); // {value: "b", done: false}
console.log( iterator.next() ); // {value: undefined, done: true}
ログイン後にコピー
ログイン後にコピー

1.2 簡単な実装

🎜 データ構造ごとに異なるトラバーサー実装メソッドがあります。単純に配列トラバーサー メソッドを実装します。 🎜
let obj = {
  0: 'a',
  1: 'b',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};

console.log( Object.keys(obj) ); // ["0", "1", "length"]

for (let v of obj) {
  console.log(v); // 依次打印出:"a", "b"。
}

for (let k in obj) {
  console.log(k); // 依次打印出:"0", "1", "length"。
}
ログイン後にコピー
ログイン後にコピー

1.3 return & throw

🎜 トラバーサー オブジェクトの next メソッドをデプロイすることに加えて、returnthrow も使用できます。 メソッド。 return メソッドは、for of ループを早期に終了するときに (通常はエラーまたは break ステートメントのトリガーにより) 呼び出されます。 throw メソッドは主に Generator 関数と組み合わせて使用​​されます。このメソッドは一般的なトラバーサー オブジェクトでは使用されないため、紹介されません。 🎜
for (let v of [1, 2, 3])  {
  console.log(v); // 依次打印出:1, 2, 3。
}
ログイン後にコピー
ログイン後にコピー
🎜2 ネイティブ サポート🎜

2.1 デフォルトでトラバーサーを保持します

🎜 デフォルトでトラバーサー インターフェイスを保持するデータ構造は次のとおりです:
基本タイプ: Array、 >Set、Map (4 つの基本データ コレクション: ArrayObjectSet >マップコード>)。 <br>配列のようなオブジェクト: <code>argumentsNodeListString。 🎜
let [...a] = [3, 2, 1]; // [3, 2, 1]
let b = [...[3, 2, 1]]; // [3, 2, 1]
ログイン後にコピー
ログイン後にコピー
🎜トラバーサーと以前のトラバーサル メソッド
データ コレクションにトラバーサー インターフェイスがあるからといって、データ コレクションを走査するすべてのメソッドがこのインターフェイスを使用するとは限りません。実際には、いくつかの新しいメソッドと、ES6 で追加された特定のメソッドのみが使用されます。これらについては、以下で紹介します。配列の場合、forfor of を使用すると同じメンバーにアクセスできますが、実際の操作は異なります。 🎜
for (let v of G()) {
  console.log(v); // 依次打印出:1, 2, 3, 4, 5
}

function* G() {
  yield 1;
  yield* [2,3,4];
  yield 5;
}
ログイン後にコピー
ログイン後にコピー
🎜オブジェクトにはデフォルトのトラバーサー インターフェイスがありません
オブジェクトにはデフォルトのトラバーサー インターフェイスがないのはなぜですか?これは 2 つの側面から説明する必要があります。まず、トラバーサーは線形処理構造です。非線形データ構造の場合、トラバーサー インターフェイスの展開は線形変換の展開と同じです。次に、オブジェクトは元々順序付けされていないコレクションです。順序付けしたい場合は、代わりに Map を使用できます。これは、誰もが独自の強みを持ち、誰もが独自の義務を負っていることを意味します。フンコロガシがフン玉を転がさずに蜂蜜を集めに行ったら、花売り娘は苦しむかもしれません。 🎜

自行生成的类数组对象(拥有length属性),不具备遍历器接口。这与String等原生类数组对象不同,毕竟人家是亲生的,一出生就含着金钥匙(也不怕误吞)。不过我们可以将数组的遍历器接口直接应用于自行生成的类数组对象,简单有效无副作用。

let obj = {
  0: 'a',
  1: 'b',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};

let iterator = obj[Symbol.iterator]();
console.log( iterator.next() ); // {value: "a", done: false}
console.log( iterator.next() ); // {value: "b", done: false}
console.log( iterator.next() ); // {value: undefined, done: true}
ログイン後にコピー
ログイン後にコピー

为对象添加遍历器接口,也不影响之前不使用遍历器的方法,比如for in, Object.keys等等(两者不等同)。

let obj = {
  0: 'a',
  1: 'b',
  length: 2,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};

console.log( Object.keys(obj) ); // ["0", "1", "length"]

for (let v of obj) {
  console.log(v); // 依次打印出:"a", "b"。
}

for (let k in obj) {
  console.log(k); // 依次打印出:"0", "1", "length"。
}
ログイン後にコピー
ログイン後にコピー

2.2 默认调用遍历器

for of  
for of是专门用来消费遍历器的,其遍历的是键值(for in遍历的是键名)。

for (let v of [1, 2, 3])  {
  console.log(v); // 依次打印出:1, 2, 3。
}
ログイン後にコピー
ログイン後にコピー

扩展运算符  
无论是解构赋值或扩展运算都是默认调用遍历器的。

let [...a] = [3, 2, 1]; // [3, 2, 1]
let b = [...[3, 2, 1]]; // [3, 2, 1]
ログイン後にコピー
ログイン後にコピー

yield*  
Generator函数中有yield*命令,如果其后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

for (let v of G()) {
  console.log(v); // 依次打印出:1, 2, 3, 4, 5
}

function* G() {
  yield 1;
  yield* [2,3,4];
  yield 5;
}
ログイン後にコピー
ログイン後にコピー

其它场合  
有些接受数组作为参数的函数,会默认使用数组的遍历器接口,所以也等同于默认调用。比如Array.from(), Promise.all()

相关推荐:

angularjs关于页面模板清除的使用方法

在JS中用slice封装数组方法

以上がイテレータは、データ コレクションにアクセスするための統一インターフェイス メソッドです。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

コンピュータのマザーボードの内部インターフェイスとは何ですか? コンピュータのマザーボードの内部インターフェイスに関する推奨される入門 コンピュータのマザーボードの内部インターフェイスとは何ですか? コンピュータのマザーボードの内部インターフェイスに関する推奨される入門 Mar 12, 2024 pm 04:34 PM

パソコンを組み立てる際、設置作業は簡単ですが、誤ってCPUラジエーターの電源線をSYS_FANに差し込んでしまうなど、配線に問題が発生することが多く、ファンは回転しますが、ファンが回転しない場合があります。コンピュータの電源がオンになると、F1 エラー「CPUFanError」が発生し、CPU クーラーがインテリジェントに速度を調整できなくなります。コンピューターのマザーボード上の CPU_FAN、SYS_FAN、CHA_FAN、および CPU_OPT インターフェイスに関する一般的な知識を共有しましょう。コンピュータのマザーボード上の CPU_FAN、SYS_FAN、CHA_FAN、および CPU_OPT インターフェイスに関する一般科学 1. CPU_FANCPU_FAN は、CPU ラジエーター専用のインターフェイスであり、12V で動作します。

Go 言語の一般的なプログラミング パラダイムと設計パターン Go 言語の一般的なプログラミング パラダイムと設計パターン Mar 04, 2024 pm 06:06 PM

最新の効率的なプログラミング言語である Go 言語には、開発者が高品質で保守可能なコードを作成するのに役立つ豊富なプログラミング パラダイムと設計パターンがあります。この記事では、Go 言語の一般的なプログラミング パラダイムと設計パターンを紹介し、具体的なコード例を示します。 1. オブジェクト指向プログラミング Go 言語では、構造体とメソッドを使用してオブジェクト指向プログラミングを実装できます。構造を定義し、その構造にメソッドをバインドすることにより、データのカプセル化と動作バインディングのオブジェクト指向機能を実現できます。パッケージマイニ

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ Mar 16, 2024 pm 12:09 PM

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

フロントエンドの面接官からよく聞かれる質問 フロントエンドの面接官からよく聞かれる質問 Mar 19, 2024 pm 02:24 PM

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

PHP インターフェースの概要とその定義方法 PHP インターフェースの概要とその定義方法 Mar 23, 2024 am 09:00 AM

PHP インターフェースの概要とその定義方法 PHP は、Web 開発で広く使用されているオープンソースのスクリプト言語であり、柔軟性があり、シンプルで強力です。 PHP では、インターフェイスは複数のクラス間で共通のメソッドを定義し、ポリモーフィズムを実現し、コードをより柔軟で再利用可能にするツールです。この記事では、PHP インターフェイスの概念とその定義方法を紹介し、その使用法を示す具体的なコード例を示します。 1. PHP インターフェイスの概念 インターフェイスはオブジェクト指向プログラミングにおいて重要な役割を果たし、クラス アプリケーションを定義します。

Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Go 言語のフロントエンド テクノロジーの探求: フロントエンド開発の新しいビジョン Mar 28, 2024 pm 01:06 PM

Go 言語は、高速で効率的なプログラミング言語として、バックエンド開発の分野で広く普及しています。ただし、Go 言語をフロントエンド開発と結びつける人はほとんどいません。実際、フロントエンド開発に Go 言語を使用すると、効率が向上するだけでなく、開発者に新たな視野をもたらすことができます。この記事では、フロントエンド開発に Go 言語を使用する可能性を探り、読者がこの分野をよりよく理解できるように具体的なコード例を示します。従来のフロントエンド開発では、ユーザー インターフェイスの構築に JavaScript、HTML、CSS がよく使用されます。

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たすかを探る Mar 19, 2024 pm 06:15 PM

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たしているかを調べるには、具体的なコード例が必要です。インターネットとモバイル アプリケーションの急速な発展に伴い、フロントエンド テクノロジーの重要性がますます高まっています。この分野では、強力なバックエンド プログラミング言語としての Golang も重要な役割を果たします。この記事では、Golang がどのようにフロントエンド テクノロジーと組み合わされるかを検討し、具体的なコード例を通じてフロントエンド分野での可能性を実証します。フロントエンド分野における Golang の役割は、効率的で簡潔かつ学びやすいものとしてです。

Java のデザイン パターンにおけるインターフェイスと抽象クラスの適用 Java のデザイン パターンにおけるインターフェイスと抽象クラスの適用 May 01, 2024 pm 06:33 PM

インターフェイスと抽象クラスは、分離と拡張性のためにデザイン パターンで使用されます。インターフェイスはメソッド シグネチャを定義し、抽象クラスは部分的な実装を提供し、サブクラスは未実装のメソッドを実装する必要があります。ストラテジ パターンでは、インターフェイスを使用してアルゴリズムを定義し、抽象クラスまたは具象クラスが実装を提供するため、アルゴリズムを動的に切り替えることができます。オブザーバー パターンでは、インターフェイスを使用してオブザーバーの動作を定義し、抽象クラスまたは具象クラスを使用して通知をサブスクライブおよびパブリッシュします。アダプター パターンでは、インターフェイスを使用して既存のクラスを適応させることができ、互換性のあるインターフェイスを実装できるため、元のコードとの対話が可能になります。

See all articles