javascriptでオブジェクト内にオブジェクトを作ったらsetTimeout関数のthis問題が複雑化した
javascriptでオブジェクト内にオブジェクトを作ったらsetTimeout関数のthis問題が複雑化した:
前回の続き。
前回の例と違うのは、クラス内から
このプログラムを実行すると
undefinedが返ってきた。
どのように書けばいいかというと、
オブジェクトの4段連鎖なら、
。
アロー関数にすればそれが定義されている場所でのthisになるので、class内メソッドをアロー関数にできないか考えてみた。
constructor内にメソッドを書く書き方が美しくないが、これはいいかもしれない
。
オブジェクトは本来こうあるべきじゃあないだろうか。
この書き方でできなくなることもある。呼び出し側で関数に
前回の続き。
前回の例と違うのは、クラス内から
setTimeoutを呼んでるのと、オブジェクト内のオブジェクトのメソッドを呼んでること。
setTimeout関数の失敗例 その2
<script>
document.addEventListener('DOMContentLoaded', function () {
'use strict';
class Test {
constructor() { this.value = "成功"; }
alert() {
alert(this.value);
}
}
class TestWrapper {
constructor() {
this.test = new Test(); //オブジェクト内にオブジェクトを作成
}
setTimeoutWrap() {
setTimeout(this.test.alert.bind(this), 100); //失敗例
}
}
const testwrapper = new TestWrapper(); //オブジェクトを作成
test01.addEventListener('click', function () {
testwrapper.setTimeoutWrap();
});
});
</script>
<button id="test01">test01</button>
undefinedが返ってきた。
成功例
どのように書けばいいかというと、setTimeout(this.test.alert.bind(this.test), 100);と書けば成功。setTimeoutで呼び出すメソッドが連鎖する場合、bindするオブジェクトも連鎖させなければならないようだ。オブジェクトの4段連鎖なら、
setTimeout(this.test.test2.test3.alert.bind(this.test.test2.test3), 100);となる setTimeout(function () { this.test.alert() }.bind(this), 100);と書いても成功。前回書いたように、括弧を付けないとオブジェクトのメソッドが関数化するので、括弧を付けて関数化させないほうがいい。オブジェクトの4段連鎖なら、setTimeout(function () { this.test.test2.test3.alert() }.bind(this), 100);となってbind(this)1つで済むので。
class内メソッドのアロー関数化
アロー関数にすればそれが定義されている場所でのthisになるので、class内メソッドをアロー関数にできないか考えてみた。<script>
document.addEventListener('DOMContentLoaded', function () {
'use strict';
class Test {
constructor() {
this.value = "成功";
this.alert = () => {
alert(this.value);
}
}
}
class TestWrapper {
constructor() {
this.test = new Test(); //オブジェクト内にオブジェクトを作成
}
setTimeoutWrap() {
setTimeout(this.test.alert, 100); //成功
}
}
const testwrapper = new TestWrapper(); //オブジェクトを作成
test01.addEventListener('click', function () {
testwrapper.setTimeoutWrap();
});
});
</script>
<button id="test01">test01</button>
オブジェクトは本来こうあるべきじゃあないだろうか。
この書き方でできなくなることもある。呼び出し側で関数に
bind(new_this)とやってアロー関数内のthisの値を書き換えられなかった。bind関数よりもアロー関数のほうが強い。
コメント
コメントを投稿