疲れたのでJavaScriptでinjectionするものを書いた。
AngularJSを使ふのに結局失敗して、Polymerを使ってゐる訳だが、AngularJSには引数名を適当なものにしておくと、ちゃんと其の引数名に対応する値が渡される素敵な仕組みが有ると云ふ。Function.prototype.toStringを見てゐることだけは知ってゐた。
阿っちが洞う云ふ実装に成ってゐるかは知らない。意外と暇潰し程度の手間で済んだ。
/** * @param (function(Object...):Object} fun * @param {Object} _this * @param {Object.<string,Object>} args * @return {function(Object...):Object} */ function inject(fun, _this, args) { 'use strict'; var params; params = fun.toString(). replace(/\r?\n/g, ' '). match(/function[^\(]*\(([^\)]*)\)/)[1]. split(','). map(function (param) { return param.trim(); }); return function () { var i = 0, iz = 0, j = 0, _arguments = []; j = 0; for (i = 0, iz = params.length; i < iz; ++i) { if (args[params[i]] !== void 0) { _arguments[i] = args[params[i]]; } else { _arguments[i] = arguments[j]; ++j; } } fun.apply(_this, _arguments); }; } function f(id, name, call) { console.log([this, id, name, call]); } inject(f, 'th', {id: 2, name: 'yu', call: 0x16})( ); inject(f, 'th', { name: 'yu', call: 0x16})(2 ); inject(f, 'th', {id: 2, call: 0x16})( 'yu' ); inject(f, 'th', {id: 2, name: 'yu' })( 0x16); inject(f, 'th', { call: 0x16})(2, 'yu' ); inject(f, 'th', { name: 'yu' })(2, 0x16); inject(f, 'th', {id: 2 })( 'yu', 0x16); inject(f, 'th', { })(2, 'yu', 0x16);
ほれ。
[ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ] [ { '0': 't', '1': 'h' }, 2, 'yu', 22 ]
因みに関数のthisを変えたくないときは、Function.prototype.bind() でthisを固定しておく。bind()は再bind出来ない。