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では普通に出来ていたことが、他のエンジンでもできるようになる。
便利ー。