bind in JS / React

## this
ES5 
thisは、そのthisが格納されている関数をさすobjectをさす
ある一定のスコープ内のオブジェクトをさす。

ES6
thisは、そのthisが定義されているthisをさす。
スコープの周辺から見つける。

## ES5の問題点
```es5.js
function Prefixer(prefix) {
    this.prefix = prefix;
}
Prefixer.prototype.prefixArray = function (arr) { // (A)
    'use strict';
    return arr.map(function (x) { // (B)
        // Doesn’t work:
        return this.prefix + x; // (C)
    });
};

```

this.prefixでPrefixerのthisを参照したいけど参照できない。in strict modeではthisはBが格納されているfunctionが指すオブジェクト、Prefixer.prototype.prefixArrayを指すためだ。

## ES5の解決策：bind(this)
bind()を使うと、thisは常に固定された値を指すようになる。
this.NAMEはその周辺のthis.NAMEを指すようになるためエラーが起こらない。

```solution1.js
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
    return arr.map(function (x) {
        return this.prefix + x;
    }.bind(this)); // (A)
};

```

## ES5の解決策：ES６の登場とArrow function!
functionとarrow functionは書き方が違うだけで使い方は全く同じと思われがちだが、thisnの指すものが違う。
arrow function内で指すthisは、その周辺からthis.NAMEを探してきてそれを指す。

```solution2.js

function Prefixer(prefix) {
    this.prefix = prefix;
}
Prefixer.prototype.prefixArray = function (arr) {
    return arr.map((x) => {
        return this.prefix + x;
    });
};

``` 

```solution3.js

class Prefixer {
  constructor(prefix) {
    this.prefix = prefix; // (A)
  }

  prefixArray (arr) {
    return arr.map(x => this.prefix + x);  // このthis.prefixはAのthis.prefixと一緒。
  }
}



```

##bindとは

> 呼び出されるたびに、その時に与えられたthis(連続するarguments)を用いて新しいfunctionを返す

呼び出したobject自身を指す。
基本object以外ささない
そのため、functional componentでは使わない。
class based componentで使う。

友人によると、
「新しくfunctionを作る」
「thisもしくは連続するarguments (...args)を使う」
ってところがポイントらしい。
そのときのthisに応じて繰り返しfunctionを作りたいときによくつかうらしい。

 ということは
呼び出されるとfunctionがthisを探す。
localにthisがない場合はglobalがthisに指定される。


```sample1.js
this.x = 9;
var module = {
  x : 81,
  getX : function() { return this.x; 
}
module.getX();  //81

var retrieveX = module.getX;
retrieveX(); // 9

var boundGetX = retrieveX.bind(module);
boundGetX(); //81

```

```sample2.js

var Button = function(content) { 
  this.content = content;
};
Button.prototype.click = function() {
  console.log(this.content + ' clicked');
}

var myButton = new Button('OK');
myButton.click();

var looseClick = myButton.click;
looseClick(); // not bound, 'this' is not myButton - it is the global object

var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton

```

```sample3.js
//bindを使わないケース

split = (splitter, str) => str.split(splitter)
split(":", "hello: good: bad:");
// ["hello", "good" "bad"]
split(" ", "hello: good: bad:");
// ["hello:", "good:", "bad:"]

//bindを使ったケース
str = "hello: good: bad:";
f = str.split.bind(str);
// thisはstrですよと知らせている
f(" ");  // ["hello:", "good:", "bad:"]
f(":");  // ["hello", "good" "bad"]
```

bind を使うとすっきりみえるとのこと。

## Reactでbind使うケース

eventHandlerつかうときによくthisとbindつかうのだけど、やり方が複数あるらしい。このへん、まだちゃんとわかってないからあとで整理するべし。

```sample4-1.js
class Toggle extends React.Component {
	constructor(props) {
		super(props);
		this.handleClick = this.handleClick.bind(this);
	}
	render() {
		return (
			<button onClick={this.handleClick}>
			{this.state.isToggleOn ? 'ON' : 'OFF'}
			</button>
			}
		)

	}
}
```

```sample4-2.js

class Toggle extends React.Component {
	constructor(props) {
		super(props);
	}
	render() {
		return (
			<button onClick={(e) => this.handleClick.bind(this)}>
			{this.state.isToggleOn ? 'ON' : 'OFF'}
			</button>
			}
		)

	}
}

```