2016-11-28 3 views
4

habe ich so etwas wie die folgenden haben ...Zuweisen von Funktionen zu Variablen in Javascript?

var setFoo = function (value1) { 
    window.localStorage.setItem('foo1', value1); 
} 

var setFoo2 = function (value2) { 
    window.localStorage.setItem('foo2', value2); 
} 

.. aber fand ich, dass ich immer wieder ...

window.localStorage.setItem('something', value); 

tat ... so habe ich beschlossen, es zu drehen in eine Funktion ...

function genericSetFoo(name, value) { 
    window.localStorage.setItem(name, value); 
} 

... und die folgende Stelle haben ...

var setFoo = genericSetFoo('foo1', value1); 
var setFoo2 = genericSetFoo('foo2', value2); 

... aber jetzt, wenn ich versuche setFoo1(value1) oder setFoo2(value2) zu nennen, die Anwendung klagt über value1 und value2undefined zu sein. Was mache ich falsch? Ich meine, ich könnte noch tun ...

var setFoo = function(value1) { genericSetFoo('foo1', value1) }; 
var setFoo2 = function(value2) { genericSetFoo('foo2', value2) }; 

... und es funktioniert auch ... aber es Niederlagen der ganze Sinn, wenn ich die Funktion in jedem Fall neu zu definieren haben. Wie gehe ich damit um?

Antwort

1

Was mache ich falsch?

Du nennst window.localStorage.setItem() stattdessen eine Funktion der Rücksendung, die window.localStorage.setItem() aufruft. Denken Sie daran, wenn Sie eine Funktion aufrufen und sie einer Variablen zuweisen, die Sie den Rückgabewert dieser Funktion zuweisen, nicht die Funktion selbst.

Zum Beispiel, wenn Sie das tun:

function a() { return 2 }; 

var two = a(); 

.. erwarten Sie die Variable two2 oder eine Funktion sein? Ein weiteres Beispiel, wenn Sie das tun:

var x = document.getElementById('foo'); 

.. do you die Variable x erwarten ein DOM-Element oder eine Funktion enthalten?

So müssen Sie eine Funktion zurückzukehren, anstatt eine Funktion aufzurufen:

function genericSetFoo(name) { 
    return function (value) { 
     window.localStorage.setItem(name, value); 
    } 
} 

So, jetzt können Sie tun:

var setFoo1 = genericSetFoo('foo1'); 
+0

Oh, danke. Das ist wirklich interessant. Dies scheint für mein gegenwärtiges Verständnis die verständlichste Lösung zu sein. Einige der anderen Benutzer haben jedoch etwas über "currying" oder "partielle Anwendung" erwähnt ... Was sagen Sie dazu im Vergleich? Geschätzt. – Grateful

+0

Okay, ich habe gerade gemerkt, dass deine Methode tatsächlich ein Beispiel für Curry war. Aber wie unterscheidet sich das von der '.bind' Technik? – Grateful

+0

@Graeful: Dies erfordert keine zusätzlichen Sprachfunktionen (wie ES5 '.bind()') und funktioniert bis zur ursprünglichen Netscape-Version von JavaScript und der ursprünglichen IE-Version von jscript. Wenn Sie einmal verstanden haben, wie Funktionen und Schließungen funktionieren, können Sie zusätzliche Sprachfunktionen wie '.bind()' selbst implementieren. – slebetman

2

Sie können .bind() in dieser Situation verwenden. Diese Technik wird als „Teil-Funktionsauswertung“ bekannt:

var setFoo = genericSetFoo.bind(null, 'foo1'); 
var setFoo2 = genericSetFoo.bind(null, 'foo2'); 

setFoo(value1); 

Wenn Sie mit lodash oder unterstreichen, können Sie _.partial() verwenden, die von .bind unterscheidet, dass es nicht das erste Argument erfordert und nicht rebind den this Wert:

var setFoo = _.partial(genericSetFoo, 'foo1'); 
var setFoo2 = _.partial(genericSetFoo, 'foo2'); 
1

Was mache ich falsch?

Wenn Sie das tun:

var setFoo = genericSetFoo('foo1', value1); 

Sie genericSetFoo() sind aufgerufen wird und den Wert von ihm setFoo zurück zuweisen. Jedoch zum Zeitpunkt der Initialisierung setFoo (und damit genericSetFoo() aufrufen) erhalten Sie undefined Fehler, wenn window.localStorage.setItem(name, value) versucht, das Argument zu seinem value Parameter übergeben verwendet.

Verwandte Themen