0
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.ジェネレーター

ジェネレーターとはイテレーターを生成するための特殊な関数
→ より簡略化してイテレーターを作成することができる!!

####基本構文

#####イテレーター

// 基本のイテレーターの定義
function genIterator() {
  return {
    next function(){
      return {
        done: true / false,
        value: 
      }
    }
  }
}

#####ジェネレーター


// ジェネレーターに書き換え
// functionの後ろに*をつけることでこの関数がジェネレーター関数であることを示している
function* gen(){
  if(ループ継続){
    // 下記のyieldでイテレーターの部分を表す
    // ここでdoneがfalse, value(値)であることを指す
    yield ;
  } else {
    // ここのreturnでdoneがtrue, value値を表す → ループを抜け出す
    return ;
  }
}

####例1

簡単なジェネレーターの例

function* gen(){
  yield 1; //①
  yield 2; //②
  return 3; //③
}

// 変数にgen()を格納
// ジェネレーター関数を実行することでイテレーターが帰ってくる
const it = gen();
// イテレーターのnextメソッドを使用
console.log(it.next());
console.log(it.next());
console.log(it.next());
// {value: 2, done: false} → ①のyield
// {value: 2, done: false} → ②のyield
// {value: 3, done: true} → ③のyield
// 上記のように出力される

####例2

より実践的な例
前回の記事で作成したイテレーターをジェネレーターに書き換えていく

function genIterator(max = 10){
  let i = 0;

  return{
    next: function(){
      if(i >= max){
        return{
          done: true
        }
      } else {
        return{
          done: false,
          value: i++
        }
      }
    }
  }
}

const it = genIterator();
console.log(it.next());

上記のイテレーターをジェネレーターに書き換えると以下の通りになる

function* genIterator(max = 10){
  let i = 0;
  // whileを使って条件分岐
  while(i < max){
    yield i++;
    }
    // returnは省略可能(i < maxになった時点でループ終了)
    return ;
  }

const it = genIterator(10);

let a = it.next();
while(!a.done){
  // 0から9が出力される
  console.log(a.value);
  a = it.next();
}

####例3

Symbolを使って反復可能オブジェクトにする

function* genIterator(max = 10){
  let i = 0;
  while(i < max){
    yield i++;
    }
    return ;
  }

const obj = {
  // SymbolのイテレーターにgenIteratorを追加
  [Symbol.iterator]: genIterator
}
// for...ofを使用して出力しても同じ結果に
// ジェネレーターでは反復可能オブジェクトを作成せずにofの後ろに直接genIteratorを入れて実行しても使える
for(const i of obj){
  console.log(i);
}

ジェネレーターを反復可能オブジェクトに入れることも可能

const obj = {
  [Symbol.iterator]: function* genIterator(max = 10){
    let i = 0;
    while(i < max){
      yield i++;
      }
      return ;
    }
}


for(const i of obj){
  console.log(i);
}

###2.反復可能オブジェクト(ジェネレーター)

####例1

下記の反復可能オブジェクトを使用したイテレーターをジェネレーターに書き換える

イテレーター

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

Object.prototype[Symbol.iterator] = function(){
	const keys = Object.keys(this);

	let i = 0;
	let _this = this;
	return{
		next(){
			let key = keys[i++];
		return{
			done: i > keys.length,
			value: [key, _this[key]]
			}
		}
	}
}
````

ジェネレーター

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

// ジェネレーター関数なのでfunctionの後ろに*をつける
Object.prototype[Symbol.iterator] = function* (){
	// for..inを使用
	// thisはオブジェクトの参照を保持している
	for(let key in this){
		yield [key, this[key]];
	}
}
// 以上で書き換え終了

for(let [k,v] of items){
//itemsのプロパティの値が出力される
	console.log(k, v);
}

今日はここまで!

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

0
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
0
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?