2016-08-31 6 views
0

Ich habe ein Objekt:JavaScript aufrufen Funktion Objektwerte mit als Parameter

var obj = { 
    foo: 'foo', 
    bar: 'bar' 
}; 

Und ich habe eine Funktion:

var f = function(bar, foo) { 
    // Do something with bar and foo 
}; 

Gibt es eine Möglichkeit, ich dynamisch die Funktion mit dem Objekt aufrufen kann, so dass obj ['foo'] als 'foo' Parameter übergeben wird und obj ['bar'] als 'bar' Parameter übergeben wird? Beachten Sie, dass ich die tatsächlichen Namen der Schlüssel und Werte oder die Funktionsargumentnamen möglicherweise nicht kenne, die angegebenen sind nur ein Beispiel, so dass f.call(this, obj['bar'], obj['foo']); nicht funktioniert.

+0

Sie müßten die Argumentnamen der Funktion zu prüfen, einen Array der Argumente in der richtigen Reihenfolge erstellen, und dann 'f.apply (null, args)' ... Vielleicht hat jemand kann von hier aus eine Implementierung bereitstellen ... – deceze

+0

Sie möchten Objekteigenschaftsnamen basierend auf den Namen von Funktionsargumenten übergeben? Das ist keine gute Idee. – Maxx

+0

Nicht in der Lage zu verstehen, was Sie wollen. ausgearbeitet – ajaykumar

Antwort

1

Sicher, in ES6

var f = function({bar, foo}) { 
 
    console.log('foo', foo, 'bar', bar) 
 
}; 
 

 
var obj = { 
 
    foo: '11', 
 
    bar: '22' 
 
}; 
 

 

 
f(obj)

+0

Nicht ganz das Gleiche ... – deceze

+0

Dies funktioniert möglicherweise nicht als 'Beachten Sie, dass ich die tatsächlichen Namen nicht kennen kann der Schlüssel und Werte oder die Funktion Argumentnamen – eithed

0

könnten Sie prüfen, ob zur Verfügung gestellt Argument Objekt und verwenden Sie dann Destrukturierung

var obj = { 
 
    foo: 'foo', 
 
    bar: 'bar' 
 
}; 
 

 
var f = function(foo, bar) { 
 
    if(typeof arguments[0] == 'object') var {foo, bar} = arguments[0]; 
 
    console.log('Foo: ' + foo); 
 
    console.log('Bar: ' + bar) 
 
}; 
 

 
f(obj); 
 
f('lorem', 'ipsum');

+0

Auch nicht ganz das gleiche ... – deceze

0

Sie könnten das Objekt zur Funktion bind.

Die bind() Methode erzeugt eine neue Funktion, die, wenn sie aufgerufen wird, dessen this Schlüsselwort an den vorgesehenen Wert eingestellt hat, mit einer gegebenen Sequenz von Argumenten jeder vorhergehenden bereitgestellt, wenn die neue Funktion aufgerufen wird.

var obj = { 
 
     foo: 'foo', 
 
     bar: 'bar' 
 
    }, 
 
    f = function(k) { 
 
     console.log(this[k]); 
 
    }.bind(obj); 
 

 
f('foo');

1

Basierend auf deceze Kommentar schaffte ich es mit einer Lösung zu kommen. Ich bin mir nicht ganz sicher, wie schnell es ist, aber es macht den Job erledigt. Verbesserungen sind willkommen! Danke für die Hilfe von allen.

habe ich diese Funktion von this answer:

function getParameterNames(fn){ 
    var fstr = fn.toString(); 
    return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi,'').replace(/\s/gi,'').split(','); 
} 

und machte folgende:

var obj = { 
    foo: 'foo', 
    bar: 'bar' 
}; 

var f = function(bar, foo) { 
    // Do something with bar and foo 
}; 

var sortedArgs = []; 
getParameterNames(f).forEach(function(item) { 
    sortedArgs.push(args[item]); 
}); 

f.apply(this, sortedArgs); 
+1

Was passiert, wenn Ihre Quelle transpiled und/oder minimiert wird? – georg

+0

Zu beachten: Was Sie tun, ist in etwa, wie Angulars Injektion funktioniert, und um mit der Minimierung umzugehen, hat es eine explizite Annotationssyntax, in der Sie die Parameter als Strings * too * auflisten müssen. Also, ja, das ist ein echtes Problem und das ist nicht allgemein anwendbar ... – deceze

+0

Verständlich. Ich habe tatsächlich eine Vielzahl von Möglichkeiten, wie die Methode mit bestimmten Argumenten aufgerufen werden kann, und dies (unter Verwendung eines Objekts) war eine der Möglichkeiten. Die anderen Möglichkeiten rufen die Methode mit Argumenten auf, die auf der Reihenfolge basieren, in der sie übergeben werden sollen. Der Hauptzweck davon ist, dass es für die interne Entwicklung verwendet wird, so dass es nicht minimiert werden würde. – driima

0

Sie können eine Funktion schreiben, die Ihre Funktion wickeln und neue Funktion verwenden, anstatt zu bekommen, was Sie wollen .

function wrapper(fn) { 
 
    var fnString = fn.toString(); 
 
    var fnRegex = /\((.*)\)/; 
 

 
    var params = fnString 
 
    .match(fnRegex)[1] 
 
    .replace(/\s/, '') 
 
    .split(',') 
 
    .filter(function(arg) { 
 
     return arg; 
 
    }); 
 

 
    return function (o) { 
 
    var args = params 
 
     .map(function(arg) { 
 
     return o[arg]; 
 
     }); 
 
    return fn.apply(null, args); 
 
    } 
 
} 
 

 
// Example: your function. 
 
function yourFunc(foo, bar) { 
 
    console.log('my foo: ' + foo); 
 
    console.log('my bar: ' + bar); 
 
} 
 

 
// wrap your function and use new function instead. 
 
var enhancedFunc = wrapper(yourFunc); 
 

 
enhancedFunc({foo: 1, bar: 2});

+0

Können Sie beschreiben, wie der Wrapper funktioniert und wie er die Parameter basierend auf den Schlüsseln in der richtigen Reihenfolge an die Funktion übergibt? – driima

+0

Zuerst analysiert es 'fn.toString()', um ein Array von Parametern in der richtigen Reihenfolge zu erhalten. Im Beispiel 'fn.toString()' => ''Funktion yourFunc (foo, bar) {...}'' => ''foo, bar'' =>' [' foo ',' bar '] '. Danach gibt es eine neue Funktion zurück, die neue Funktion verwendet das obige Array, um ein Array von Werten zu erhalten, und ruft 'fn' mit diesem Array auf,' ['foo', 'bar'] '(map with' o') => ' [1, 2] '=>' fn.apply (null, [1, 2]) '. – Caojs

Verwandte Themen