1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】反復処理⑥ 反復可能オブジェクト(イテレーター)

Posted at

#はじめに

Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。

前回の記事

#目的

  • 反復処理についての理解を深める

#本題
###1.反復可能オブジェクト

イテレーターを使って反復可能オブジェクトに書き換える

####前提とゴール

Object.entiresを必要とせず、for...ofの中でobjを使えるようにしたい

const obj = {
	prop1: 'value1',
	prop2: 'value2',
	prop3: 'value3'
}

// 通常のオブジェクトの場合はfor...ofの反復操作はできないので下記のように配列に置き換える
const items = Object.entries(obj);
for (let item of items) {
	console.log(item);
}

####イテレーターの準備

const obj = {
	prop1: 'value1',
	prop2: 'value2',
	prop3: 'value3'
}
// イテレーターを準備
Object.prototype[Symbol.iterator] = function(){
	return {
		// nextメソッドが必要
		next(){
			return{
				// とりあえず無限ループしないようにtrue
				done: true,
				// こちらも仮で0にする
				value: 0
			}
		}
	}
}

####プロパティの値を取得する

thisを使って取得する 

// for...ofで使えるようにitemsに変数を変更
const items = {
	prop1: 'value1',
	prop2: 'value2',
	prop3: 'value3'
}

Object.prototype[Symbol.iterator] = function(){
	// objへの参照がthisに含まれている
	console.log(this);
	// このthisに値を詰めていって、下記のvalueで返却する
	return {
		next(){
			return{
				done: true,
				value: 0
			}
		}
	}
}
// const items = Object.entries(obj);
for (let item of items) {
	// objの値が出力される prop1: "value1",,,,,,
	console.log(item);
}

実際に取得してみる


const items = {
	prop1: 'value1',
	prop2: 'value2',
	prop3: 'value3'
}

Object.prototype[Symbol.iterator] = function(){
	// このようにするとプロパティが配列になったものがkeysに格納される
	const keys = Object.keys(this);
	// keysの値を一つずつ取っていきたい
	// 変数iを定義し、iが+1されるごとにkeysからキー情報を取得してそれを元に値を取得していく
	const i = 0;
	return {
		// next()が呼び出されてた時に値を一つずつ取得していく
		next(){
			let i = keys[i];
			// 省略して上記にi++でも可
			i++;
			return{
				done: true,
				value: 0
			}
		}
	}
}
// const items = Object.entries(obj);
for (let item of items) {
	console.log(items);
}

thisの呼び出し元が実行するコンテキストによって参照先に変わるのでその確認をする

// objに変数を変更
const obj = {
	prop1: 'value1',
	prop2: 'value2',
	prop3: 'value3'
}

Object.prototype[Symbol.iterator] = function(){
	// 関数内で呼ばれたthisはwindowオブジェクトを呼び出す
	const keys = Object.keys(this);
	let i = 0;
	// ここでreturn内のthisもobjの値を取れるように設定
	let _this = this;
	return {
		next(){
			let key = keys[i];
			i++;
			// ここで取れるthisはnextという値が入ったthisが取れてくるので下記のように書かない
			// console.log(this);
			// 下記の_thisではスコープチェーンを辿ってnextのwindowオブジェクトを参照する
			// console,log(_this);
			return{
				// ループの終了条件追加
				// 配列の要素数のがiより大きくなった=true=終了
				done: i > keys.length,
				// ここでvalueを設定
				// entriesと同じように配列で渡したいので[]でkeyと_thisのkeyをもとに値を取得する
				value: [key, _this[key]]
			}
		}
	}
}
// const items = Object.entries(obj);
// 分割代入でk,vとして値を渡す
for (let [k,v] of obj) {
	console.log(k,v);
	// 出力結果はprop1,value1.....となる
}

今日はここまで!

#参考にさせて頂いた記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?