uncurryThis 関数
にて大変有用な書き方を身に着けた。
Function.prototype.bindとFunction.prototype.callの黒魔術的なもの。
obj.hasOwnProperty("prop");
と書くところをcallで書くと
var func = Object.prototype.hasOwnProperty; func.call(obj, "prop");
と書ける。さらにcallをbindしてみると
var func2 = func.call.bind(func); func2(obj, "prop");
となる。さらに、bindをbindすると
var func3 = func.bind.bind(func.call)(func); func3(obj, "prop");
ここで、func.bindや、func.callはbindで束縛されるので、Function.prototype.bindやFunction.prototype.call(===Function.prototype.bind.call)と同じになるので。
var bind = Function.prototype.bind; var func4 = bind.bind(bind.call)(func);
となる。
var bind = Function.prototype.bind, uncurryThis = bind.bind(bind.call); var hasOwn = uncurryThis(Object.prototype.hasOwnProperty); var obj = Object.create(null); obj.foo = "FOO"; hasOwn(obj, "foo"); // true
と、束縛したいオブジェクトを第一引数にして実行できるようになる。
上記、hasOwnPropertyの例では、オブジェクトがObjectを継承していないことを恐れて、Object.prototype.hasOwnProperty.call(obj, "foo")などとやらなくても簡単に書けるようになるわけだ。
これができると、Mozilla JavaScript 1.6 の機能であるArray および String の汎用化のようなものを簡単に定義できる。
function f1 () { Array.slice(arguments).forEach(function(arg){ // ... }); } function f2 () { return Array.map(arguments, function(str){ return str.toUpperCase(); }) }
などなど、Mozilla JavaScriptでは普通に出来ていたことが、他のエンジンでもできるようになる。
便利ー。