Funktionen ohne Namen
Einfach ausgedrückt ist ein Lambda eine Funktion ohne Namen oder eine anonyme Funktion. Ein kleines Stück ausführbaren Codes, das wie eine Variable weitergegeben werden kann. In JavaScript:
function () {}; // very simple
Lassen Sie uns nun einige Verwendungszwecke für diese Lambdas sehen.
Kesselschildcode abstrahieren
Lambdas können verwendet werden, um Boilerplate-Code zu abstrahieren. Zum Beispiel Schleifen. Wir sind es gewohnt, den ganzen Tag zu schreiben for
und zu while
schleifen. Dies ist jedoch Code, der nicht geschrieben wird. Wir könnten den Code innerhalb der Schleife, dem wichtigsten Teil der Schleife, extrahieren und den Rest abstrahieren:
for (var i=0; i<array.length; i++) {
// do what something useful with array[i]
}
Durch die Verwendung forEach
von Array-Objekten wird:
array.forEach(function (element, index) {
// do something useful with element
// element is the equivalent of array[i] from above
});
Die obige Abstraktion mag nicht so nützlich sein, aber es gibt andere Funktionen höherer Ordnung forEach
, die viel nützlichere Aufgaben ausführen. Zum Beispiel filter
:
var numbers = [1, 2, 3, 4];
var even = [];
// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
if (numbers[i] % 2 === 0) {
even.push(numbers[i]);
}
}
alert(even);
// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
return number % 2 === 0;
});
alert(even);
Verzögerung bei der Codeausführung
In einigen Umgebungen, in denen das Konzept des Ereignisses verfügbar ist, können wir Lambdas verwenden, um auf Ereignisse zu reagieren, die zu einem bestimmten Zeitpunkt auftreten können.
window.onload = function () {
alert("Loaded");
};
window.setTimeout(function () {
alert("Code executed after 2 seconds.");
}, 2000);
Dies hätte auf andere Weise geschehen können, aber diese sind ziemlich ausführlich. In Java gibt es beispielsweise die Runnable
Schnittstelle.
Funktionsfabriken
Bis zu diesem Zeitpunkt haben wir Lambdas hauptsächlich wegen seiner syntaktischen Zuckerfähigkeiten verwendet. Aber es gibt Situationen, in denen Lambdas viel nützlicher sein können. Zum Beispiel können wir Funktionen haben, die Lambdas zurückgeben. Angenommen, wir haben eine Funktion, deren Rückgabewerte zwischengespeichert werden sollen.
var users = [];
var getUser = function (name) {
if (! users[name]) {
// expensive operations to get a user. Ajax for example
users[name] = user_from_ajax;
}
return users[name];
};
Später stellen wir möglicherweise fest, dass wir eine ähnliche Funktion haben:
var photos = [];
var getPhoto = function (name) {
if (! photo[name]) {
// expensive operations to get a user. Ajax for example
photos[name] = photo_from_ajax;
}
return photos[name];
};
Da ist eindeutig ein Muster drin, also lasst es uns weg abstrahieren. Verwenden wir Memoization .
/**
* @param {Array} store Data structure in which we cache lambda's return values
* @param {Function} lambda
* @return {Function} A function that caches the result of calling the lambda param
*/
var memoize = function (store, lambda) {
// return a new lambda
return function (name) {
if (! store[name]) {
// Execute the lambda and cache the result
store[name] = lambda(name);
}
return store[name];
};
};
var getUsers = memoize([], function (name) {
// expensive operations to get a user. Ajax for example
});
var getPhotos = memoize([], function (name) {
// expensive operations to get a photo. Ajax for example
});
Wie Sie sehen können, konnten wir mithilfe von Lambdas die Caching- / Memoisierungslogik abstrahieren. Wenn es für das andere Beispiel einige Problemumgehungen gab, glaube ich, dass dieses spezielle Problem mit anderen Techniken kaum gelöst werden kann. Wir haben es geschafft, einige wichtige Boilerplate-Codes an einem einzigen Ort zu extrahieren. Ganz zu schweigen davon, dass wir die users
und photos
globalen Variablen losgeworden sind.
Wenn ich mir dein Profil ansehe, sehe ich, dass du hauptsächlich Python-Benutzer bist. Für das obige Muster hat Python das Konzept der Dekorateure. Es gibt viele Beispiele im Internet für Memoization Decorators. Der einzige Unterschied besteht darin, dass Sie in Python höchstwahrscheinlich eine benannte verschachtelte Funktion in dieser Decorator-Funktion haben. Der Grund dafür ist, dass Python nur Lambdas mit einem Ausdruck unterstützt. Das Konzept ist jedoch dasselbe.
Als Beispiel für die Verwendung von Python Lambda. Der obige Code, in dem wir gerade Zahlen gefiltert haben, kann in Python folgendermaßen dargestellt werden:
filter(lambda x: x % 2 == 0, [1, 2, 3, 4])
Wie auch immer, Lambdas sind ohne Verschlüsse nicht so mächtig. Verschlüsse machen das Konzept der Lambdas so mächtig. In meinem Memoisierungsbeispiel habe ich Verschlüsse verwendet, um einen Verschluss um den store
Parameter herum zu erstellen. Auf diese Weise habe ich auch dann Zugriff auf diesen Parameter, wenn die memoize
Funktion ihr Ergebnis zurückgegeben hat (ein Lambda).