own/ownWithOrgの使い方
JavaScriptは非同期で処理を行う言語です。そして、オブジェクト自身を意味する this が頻繁に使われます。しかし、非同期処理の後はthisが思ったものではなくなっていたりして、困った経験があるのではないでしょうか。
例えば次のような処理です。
| var Hello = { | |
| name: "hifive", | |
| message: function() { | |
| return "Hello, " + this.name; | |
| } | |
| } | |
| Hello.message(); // "Hello, hifive" |
これは普通ですが、非同期処理に変更します。
| var Hello = { | |
| name: "hifive", | |
| message: function() { | |
| setTimeout(function() { | |
| return "Hello, " + this.name; | |
| }, 1000); | |
| } | |
| } | |
| Hello.message(); |
この時の this は Windowオブジェクトになるので、nameはありません。このようにスコープが変わってしまうと this の値も変化します。
その解決策として、次のように実行してみます。
| 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メソッドを提供しています。例えばコントローラの中で、次のように使います。
| $.ajax({ | |
| : | |
| }) | |
| .then(this.own(function(response) { | |
| this // hifiveのコントローラ | |
| })); |
さらにhifiveのコントローラだけでなく、本来のthisを使いたい場合にはownWithOrgがあります。
| $.ajax({ | |
| : | |
| }) | |
| .then(this.ownWithOrg(function(original, response) { | |
| this // hifiveのコントローラ | |
| original // 元々のthis | |
| })); |
このようにして this による混乱を抑えられるようになります。
サンプルコードをJSFiddleにアップロードしています。各処理における this の値の違いについて確認してみてください。
コメントは受け付けていません。