私はこの機能を持っているとしましょう:
function doSomething(uno, dos, tres) {
// do something
}
そしてこのオブジェクト:
{
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomethingこのマッピングを指定して呼び出すにはどうすればよいですか? を使用してみましたが、オブジェクトではなくリストを取得する必要があるapplyようです。apply
私はこの機能を持っているとしましょう:
function doSomething(uno, dos, tres) {
// do something
}
そしてこのオブジェクト:
{
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomethingこのマッピングを指定して呼び出すにはどうすればよいですか? を使用してみましたが、オブジェクトではなくリストを取得する必要があるapplyようです。apply
以下のように使用して、上記のようにオブジェクトの各プロパティを参照でき.ます。
doSomething(obj.uno, obj.dos, obj.tres)
Function.apply配列のようなオブジェクト1を関数呼び出しに適用するためにのみ使用できます。Python の「キーワード引数展開」に相当するものはなく、手動で行う必要があります。
var opts = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomething(opts.uno, opts.dos, opts.tres)
配列のようなオブジェクトから始めた場合:
var arr = ['baz', 'foo', 'bar']
doSomething.apply(window, arr)
または、2 つを組み合わせる (パラメーター シーケンスへの構成をより早く処理できるようにするため):
var arr = [opts.uno, opts.dos, opts.tres]
doSomething.apply(window, arr)
(難読化されていないコードを使用して) 2 を使用してパラメーター名を抽出し、解析を行ってから、一般的なオブジェクトを「適用」する (または適用される配列を構築する) コードを記述することは可能ですが、これは次のとおりです。 ECMAScript 仕様では直接サポートされていません。Function.toString
1配列のようなオブジェクトは、lengthと という名前のプロパティを持つオブジェクトです0..length-1。(古いバージョンの FF にはバグがありましたが、長い間修正されてきました。)
2仕様の文言 (「関数の実装依存の表現が返されます。この表現には FunctionDeclaration の構文があります..」) は、適合する ES5 実装がこの目的に使用できる出力を生成する必要があると私に信じさせます。これは実装によって異なる可能性が高く、実際にそのような使用法を調査したことはありません。
次のようなことができます。
Function.prototype.applyNamed = function (g, argArr) {
var self = this;
var argNames = self.toString().match(/function\s+\w*\s*\((.*?)\)/)[1].split(/\s*,\s*/);
var applyArgs = [];
for(var i=0; i<argNames.length; i++){
applyArgs.push(argArr[argNames[i]]);
}
self.apply(self, applyArgs);
}
function doSomething(uno, dos, tres) {
console.log('uno = ' + uno);
console.log('dos = ' + dos);
console.log('tres = ' + tres);
}
var namedArgs = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
};
doSomething.applyNamed(this, namedArgs);
印刷する必要があります:
uno = baz
dos = foo
tres = bar
本当に望むなら、実際に名前付きパラメーターを使用してメソッドを呼び出すことができますが、関数の文字列表現を解析する必要があります。この手法を使用するかどうかは議論の余地がありますが、次のようにします。
function doSomething(uno, dos, tres) {
// do something
}
var arguments = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
function callFunction(fn, namedArguments) {
var orderedArguments = [];
var parameterRegExp = /\(([\s\w\$,]*)\)/;
parameterRegExp.exec(fn.toString())[1].replace(/\s/g, '').split(',').forEach( function(parameterName) {
orderedArguments.push(namedArguments[parameterName]);
});
return fn.apply(this, orderedArguments);
}
callFunction(doSomething, arguments);