■
関数のバインディング
この章で少し分かり辛かった、関数のバインディングについてメモ。
バインディングとは、関数のなかでthisが参照するオブジェクトを実行時に結合すること。
function getName(){ return this.name } getName(); // -> '' window.name="Demo"; getName(); // -> 'Demo'
デフォルトでは、いずれのオブジェクトにも属さない形で定義された関数は、windowオブジェクトにバインドされる。
ただし、関数を呼び出すと気に特定のオブジェクトを使用しないと、そのバインディングを失ってしまうらしい。
var CoolObj = { name: 'Joe the cool object', getName: function(){ return this.name; } }; window.name = ''; //getNameはCoolObjにバインドされている CoolObj.getName(); // -> 'Joe the cool object' function callFx(fx){ return fx(); } //関数の引数としてメソッドを渡すと、バインドがデフォルトのwindowに戻ってしまう callFx(CoolObj.getName); // ->'' window.name = 'The window'; callFx(CoolObj.getName); // ->'the window'
この問題を避けるために、Prototypeではbind()という関数が用意されている。
var CoolObj = { name: 'Joe the cool object', getName: function() { return this.name; } }; CoolObj.getName() // -> 'Joe the cool object' function callFx(fx) { return fx(); } callFx(CoolObj.getName.bind(CoolObj)) // -> 'Joe the cool object'
引数の事前設定(カリー化)
メソッドをいろんなところに渡すとき、事前に引数を設定しておくと便利!なときに使う関数。
//split()に引数':'を渡してやりたいとき //ふつうなら… String.prototype.splitOnColons = function(){ return this.split(':'); '1:2:3:4'.splitOnColons(); // ->["1", "2", "3", "4"] //curry()を使うと… String.prototype.splitOnColons = String.prototype.split.curry(':');