DanLevy.net

JavaScript-Kunst

[Entwurf] Imperativ vs. Rekursiv vs. Funktional

Hero image for JavaScript-Kunst

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 Werten
function 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 und
var 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)
  1. Während native ES6-Promises großartig sind, bevorzuge ich die robuste Bluebird Promise Library.

  2. Mit oder ohne Bibliothek: Moderne Browser unterstützen Promises seit Jahren.

  3. Promises können ohne komplexe Muster genutzt werden - implizites deferred ist vorzuziehen.

  4. $q ist einfach schlecht - nutze Bluebird, siehe oben.

  5. Wichtig: Bluebirds Benchmarks sind Best-Case-Tests, beachte das bei komplexen Promise-Ketten

  6. In JavaScript implementierte David Walsh debounce in weniger als 20 Zeilen!

  7. In Java ist JDebounce, eine deutlich komplexere Bibliothek, mit ~500+ Zeilen.

  8. _ Vergleich der beiden: _

  9. Das JavaScript ist schnell und nutzt first-class Functions, um brillante Einfachheit zu erzielen.

  10. 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!