own/ownWithOrgの使い方
JavaScriptは非同期で処理を行う言語です。そして、オブジェクト自身を意味する this が頻繁に使われます。しかし、非同期処理の後はthisが思ったものではなくなっていたりして、困った経験があるのではないでしょうか。
例えば次のような処理です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Hello = { | |
name: "hifive", | |
message: function() { | |
return "Hello, " + this.name; | |
} | |
} | |
Hello.message(); // "Hello, hifive" |
これは普通ですが、非同期処理に変更します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Hello = { | |
name: "hifive", | |
message: function() { | |
setTimeout(function() { | |
return "Hello, " + this.name; | |
}, 1000); | |
} | |
} | |
Hello.message(); |
この時の this は Windowオブジェクトになるので、nameはありません。このようにスコープが変わってしまうと this の値も変化します。
その解決策として、次のように実行してみます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Hello = { | |
name: "hifive", | |
message: function() { | |
setTimeout(function() { | |
alert("Hello, " + this.name); | |
}.call(this), 1000); | |
} | |
} | |
console.log(Hello.message()); |
setTimeoutを使っているのは変わりませんが、関数をそのまま渡すのではなく、 .call(this) を追加します。そうすると、this.nameはhifiveという値が取れるようになります。callの引数に渡す値が、その関数内でのthisとして使えるようになります。
via Function.prototype.call() – JavaScript | MDN
このようにして、thisのスコープを変えることでプログラミングしやすくなります。
own/ownWithOrgの使い方
hifiveではcall(this)ではなく、ownメソッドを提供しています。例えばコントローラの中で、次のように使います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.ajax({ | |
: | |
}) | |
.then(this.own(function(response) { | |
this // hifiveのコントローラ | |
})); |
さらにhifiveのコントローラだけでなく、本来のthisを使いたい場合にはownWithOrgがあります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.ajax({ | |
: | |
}) | |
.then(this.ownWithOrg(function(original, response) { | |
this // hifiveのコントローラ | |
original // 元々のthis | |
})); |
このようにして this による混乱を抑えられるようになります。
サンプルコードをJSFiddleにアップロードしています。各処理における this の値の違いについて確認してみてください。
コメントは受け付けていません。