JavaScript-Kunst
[Entwurf] Imperativ vs. Rekursiv vs. Funktional
Imperativ vs. Rekursiv vs. Funktional
[ Work-in-progress ]
// Imperativ: Die schnellste Methode ( + sehr einfach, keine neuen Pointer oder unnötige Zuweisungen ):function fib(n) { var a = 1, b = 1, c = 0; for (var i = 1; i < n - 1; ++i) { c = a + b; a = b; b = c; } return b;}
// Rekursiv: (NUR FIREFOX oder BABELJS) ES6-Funktionsdefinition mit// Standardparametern für Initialisierungswerte (internen/rekursiven)function fib(n, current = 0, a = 1, b = 1, c = 0) { current++; c = a + b; a = b; b = c; return current >= n ? b : fib(n, current, a, b, c);}
// Lehrbuchschlechtes Beispiel - schlechte Funktionsumgebung mit mehreren äußeren veränderbaren Wertenfunction fib(n) { if (!arr) { var arr = [1, 1]; n = n - 2; } // Schlecht if (n === -1) { return [arr[0]]; } if (n === 0) { return arr; } var proc = function() { --n; arr.push(arr[arr.length - 1] + arr[arr.length - 2]); return n === 0 ? arr : proc(); // Schlecht: innere rekursive Funktion unnötig, Hinweis: Verwendete Variablen stammen aus der Elternfunktionsumgebung }; var ans = proc(); return ans[ans.length - 1];}Promises: Klasse!
// Beispiel mit Bluebird Promises undvar Promise = require("bluebird"), fs = Promise.promisifyAll(require("fs")), less = Promise.promisifyAll(require("less"));
function writeFileData(data) { return fs.writeFileAsync("/tmp/output.css", data);}// Bluebird macht so etwas möglicherweise unangenehm einfach und prägnant:fs.readFileAsync("./style.less") // Promisified readFile() aufrufen .then(less.renderAsync) // An less.render weitergeben .then(writeFileData); // Funktion, die die CSS-Inhalte erhält (1. Parameter)-
Während native ES6-Promises großartig sind, bevorzuge ich die robuste Bluebird Promise Library.
-
Mit oder ohne Bibliothek: Moderne Browser unterstützen Promises seit Jahren.
-
Promises können ohne komplexe Muster genutzt werden - implizites
deferredist vorzuziehen. -
$q ist einfach schlecht - nutze Bluebird, siehe oben.
-
Wichtig: Bluebirds Benchmarks sind Best-Case-Tests, beachte das bei komplexen Promise-Ketten
-
In JavaScript implementierte David Walsh debounce in weniger als 20 Zeilen!
-
In Java ist JDebounce, eine deutlich komplexere Bibliothek, mit ~500+ Zeilen.
-
_ Vergleich der beiden: _
-
Das JavaScript ist schnell und nutzt first-class Functions, um brillante Einfachheit zu erzielen.
-
Das Java hingegen hat deutlich mehr bewegliche Teile, Annotationen werden verwendet, um Verhalten zur Kompilierzeit anzuwenden, und es gibt eine Menge XML, einfach zur Unterhaltung!