jsのthisについて色々なページを見たものを貼り散らかしています。
貼り付けているだけです、すみません。
貼り付けたようなページを見るときは理解できた気分になるのですが、
実際のコードを見ると途端にわからないことが多いです。
今わからないのは、Reactのページにあった
this.handleChange = this.handleChange.bind(this); です。
JSを理解するにはどうしたらいいんだろうか、、
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
jsのthisについて
function Test(){
console.log("f:",this)
}
var obj = {name:"test",Test:test}
var obj = new Test();
obj.test();
console.log("obj:",this);
ES5 で bind() メソッド 呼び出し方にかかわらず関数の this の値を設定するために導入され、さらに ES2015 では、独自のthisの関連付けを行わないアロー関数が導入されました (これは包含する字句コンテキストの this の値を保持します)。
const test = {
prop: 42,
func: function() {
return this.prop;
},
};
console.log(test.func());
// expected output: 42
bind関数
- bind は一度しか機能しない
function f() {
return this.a;
}
var g = f.bind({a: 'azerty'});
console.log(g()); // azerty
var h = g.bind({a: 'yoo'}); // bind は一度しか機能しない
console.log(h()); // azerty
var o = {a: 37, f: f, g: g, h: h};
console.log(o.a, o.f(), o.g(), o.h()); // 37,37, azerty, azerty
アロー関数
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject);
関数とthis
- 関数を呼んだ時の .の前についているオブジェクトを指している。
- .を省略するとグローバルオブジェクトを参照する
メソッドチェーン
function test(){
console.log(this)
}
var obj = {name:"obj"}
test()
test.call(obj)
コンストラクタ
var obj = new function(){
this.name = "obj"
console.log(this)
}
var obj = new function() {
this.name = "obj"
name ="obj2"
console.log(this) // => {name: "obj"}
console.log(name);
}
thisの4種類のパターン
1:メソッド呼び出しパターン メソッド基準
2:関数呼び出しパターン グローバル
3:コンストラクタ呼び出しパターン
4:apply,call呼び出しパターン
//メソッド呼び出しパターン
var myObject = {
value: 10,
show: function() {
console.log(this.value);
}
}
myObject.show(); // 10
function show(){
console.log(this);
this.value = 1;
}
show();
var myObject = {
value: 1,
show: function(){
console.log(this.value);
function show(){
console.log(this.value);
}
show();
}
};
myObject.show();
var myObject = {
value: 1,
show: function() {
var self = this;
console.log(self.value); // 1
function show() {
console.log(self.value); // 1
}
show();
}
};
myObject.show();
コンストラクタ呼び出し
- 生成されるインスタンス自身が「this」にsetされる
function MyObject(value){
this.value = value;
this.increment = function(){
this.value=this.value*4;
};
}
var myObj = new MyObject(2);
console.log(myObj.value);
myObj.increment();
console.log(myObj.value);
apply, call呼び出しパターン
var myObject = {
value: 1,
show: function() {
console.log(this.value);
}
};
var yourObject = {
value: 3
};
myObject.show(); // 1
myObject.show.apply(yourObject); // 3
myObject.show.call(yourObject); // 3
呼び出しパターン2
var myObject = {
add: function(value1, value2) {
console.log(this.value + value1 + value2);
}
};
var yourObject = {
value: 3
};
myObject.add.apply(yourObject, [2, 10]); // 15
myObject.add.call(yourObject, 2, 10); // 15
- JSではECMAScript 2015(ES6)からクラスを使うことができます。
- 「new」を付けることで、生成されるインスタンスが「this」にセットされる
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class ChildPerson extends Person {
get result() {
this.checkAge();
}
checkAge() {
if(this.age < 20) {
console.log(this.name + 'は未成年です');
} else {
console.log(this.name + 'は成人です');
}
}
}
var person = new ChildPerson('太郎', 22);
person.result;
関数とthis
"thisの参照先は主に次の条件によって変化します。
実行コンテキストにおけるthis
コンストラクタにおけるthis
関数とメソッドにおけるthis
Arrow Functionにおけるthis
コンストラクタにおけるthisは、次の章である「クラス」で扱います。 この章ではさまざまな条件でのthisについて扱いますが、thisが実際に使われるのはメソッドにおいてです。 そのため、あらゆる条件下でのthisの動きを覚える必要はありません。"
関数におけるthisの基本的な参照先(暗黙的に関数に渡すthisの値)はベースオブジェクトとなります。 ベースオブジェクトとは「メソッドを呼ぶ際に、そのメソッドのドット演算子またはブラケット演算子のひとつ左にあるオブジェクト」のことを言います。 ベースオブジェクトがない場合のthisはundefinedとなります。
たとえば、fn()のように関数を呼び出したとき、このfn関数呼び出しのベースオブジェクトはないため、thisはundefinedとなります。 一方、obj.method()のようにメソッドを呼び出したとき、このobj.methodメソッド呼び出しのベースオブジェクトはobjオブジェクトとなり、thisはobjとなります。
わかったこと
コンストラクタの中でイベントハンドラにバインドしないといけないらしい
参考
this.メソッド = this.メソッド.bind(this);