Frage

Ich habe mit node.js für eine Weile auf einer Chat-Anwendung (ich weiß, sehr originell, aber ich dachte, es wäre ein gutes Lernprojekt sein). Underscore.js bietet eine Vielzahl von funktionalen Programmierung Konzepte, die interessant aussehen, so dass ich verstehen möchten, wie ein funktionsfähiges Programm in JavaScript würde eingerichtet werden.

Von meinem Verständnis der funktionalen Programmierung (was falsch sein kann), ist die ganze Idee zu vermeiden Nebenwirkungen, die im Grunde eine Funktion haben, die aktualisieren andere Variable außerhalb der Funktion so etwas wie

var external;
function foo() {
   external = 'bar';
}
foo();

wäre, eine Nebenwirkung zu schaffen, richtig? So in der Regel wollen Sie im globalen Bereich Störgrößen zu vermeiden.

Ok, so tut, wie diese Arbeit, wenn Sie mit Objekten zu tun haben und was nicht? Zum Beispiel kann eine Menge Zeit, werde ich einen Konstruktor hat und eine Init-Methode, die das Objekt initialisiert, etwa so:

var Foo = function(initVars) {
   this.init(initVars);
}

Foo.prototype.init = function(initVars) {
   this.bar1 = initVars['bar1'];
   this.bar2 = initVars['bar2'];
   //....
}

var myFoo = new Foo({'bar1': '1', 'bar2': '2'});

So ist meine Methode init absichtlich Nebenwirkungen verursacht, aber was für eine funktionelle Weise sein würde, die gleiche Art von Situation zu bewältigen?

Auch, wenn jemand mich entweder eine Python oder JavaScript-Quellcode eines Programms zeigen könnte, dass versucht möglichst funktionsfähig zu sein, dass auch sehr geschätzt werden würde. Ich fühle mich wie ich bin die Nähe von „es immer“, aber ich bin einfach nicht ganz da. Vor allem in der ich bin daran interessiert, wie die funktionale Programmierung arbeitet mit Konzept traditionellem OOP-Klassen (oder tut weg mit ihm für etwas anderes, wenn das der Fall ist).

War es hilfreich?

Lösung

Sie sollten diese Frage lesen:

Javascript als eine funktionale Sprache

Es gibt viele nützliche Links, einschließlich:

Nun, meiner Meinung nach. Viele Leute misunderstand JavaScript , möglicherweise, weil die Syntax sieht aus wie die meisten anderen Programmiersprachen (wo Lisp / Haskell / OCaml ganz anders aussehen). JavaScript ist nicht objektorientiert, es ist eigentlich eine Prototyp-basierte Sprache . Dabei spielt es keine Klassen oder klassisches Erbe sollte also nicht wirklich auf Java oder C ++ verglichen werden.

kann JavaScript besser auf eine Lisp verglichen werden; es hat Schließungen und First-Class-Funktionen. Mit ihnen können Sie andere funktionale Programmiertechniken erstellen, wie zum Beispiel Teil Anwendung ( currying).

Lassen Sie uns ein Beispiel nehmen (mit sys.puts von node.js):

var external;
function foo() {
    external = Math.random() * 1000;
}
foo();

sys.puts(external);

Um loszuwerden Effekte global Seite zu bekommen, können wir es in einem Verschluss wickeln:

(function() {
    var external;
    function foo() {
        external = Math.random() * 1000;
    }
    foo();

    sys.puts(external);
})();

Beachten Sie, dass wir nicht wirklich etwas mit external oder foo außerhalb des Rahmens tun können. Sie sind vollständig in ihrem eigenen Verschluss verpackt ist, ist unantastbar.

Nun, um loszuwerden, der external Nebeneffekt:

(function() {
    function foo() {
        return Math.random() * 1000;
    }

    sys.puts(foo());
})();

Am Ende ist das Beispiel nicht rein funktionelles, weil es kann nicht sein. Verwendung eine Zufallszahl aus dem globalen Zustand liest (einen Samen zu bekommen) und an die Konsole Druck ist ein Nebeneffekt.

Ich möchte auch darauf hinweisen, dass das Mischen der funktionalen Programmierung mit Objekten ist völlig in Ordnung. Nehmen Sie dies zum Beispiel:

var Square = function(x, y, w, h) {
   this.x = x;
   this.y = y;
   this.w = w;
   this.h = h;
};

function getArea(square) {
    return square.w * square.h;
}

function sum(values) {
    var total = 0;

    values.forEach(function(value) {
        total += value;
    });

    return total;
}

sys.puts(sum([new Square(0, 0, 10, 10), new Square(5, 2, 30, 50), new Square(100, 40, 20, 19)].map(function(square) {
    return getArea(square);
})));

Wie Sie sehen können, können Objekte in einer funktionalen Sprache mit nur gut. Einige Lisps haben sogar Dinge Eigenschaftslisten genannt, die als Objekte betrachtet werden können.

Der eigentliche Trick Objekte in einem funktionalen Stil zu verwenden ist, um sicherzustellen, dass Sie nicht auf ihren Nebenwirkungen verlasse, sondern sie als unveränderlich behandeln. Eine einfache Möglichkeit ist, wenn Sie eine Eigenschaft ändern mögen, nur ein neue Objekt mit den neuen Details schaffen und dass man passieren entlang, statt (dies ist der Ansatz verwendet, oft in Clojure und Haskell).

Ich glaube fest daran, dass funktionale Aspekte in JavaScript sehr nützlich sein können, aber letztlich sollten Sie verwenden, was der Code besser lesbar macht und was für Sie arbeitet.

Andere Tipps

Sie müssen verstehen, dass die funktionale Programmierung und objektorientierte Programmierung zueinander etwas gegensätzlich sind. Es ist nicht möglich, beides rein funktionalen und rein objektorientiert.

Funktionale Programmierung dreht sich alles um staatenlos Berechnungen. Object Oriented Programming alles über Zustandsübergänge ist. (Paraphasing diese . Hoffentlich nicht allzu schlecht)

JavaScript ist objektorientiert, als es funktionsfähig ist. Was bedeutet, dass, wenn Sie in einem rein funktionalen Stil zu programmieren möchten, können Sie große Teile der Sprache verzichten müssen. Insbesondere alle Objekt orientieren Teile.

Wenn Sie bereit sind, mehr pragmatisch zu sein darüber, gibt es einige Inspirationen aus der rein funktionalen Welt, die Sie verwenden können.

Ich versuche, die folgenden Regeln zu beachten:

Funktionen, die Berechnungen sollte nicht alten Zustand durchführt. Und Funktionen, die alte Zustand sollte nicht durchführen Berechnungen. Auch Funktionen, dass alter Zustand sollten so wenig Staat wie möglich ändern. Das Ziel ist, viele kleine Funktionen zu haben, die nur eine Sache tun. wenn Sie dann müssen etwas groß tun, komponieren Sie ein paar kleine Funktionen zu tun, was Sie brauchen.

Es gibt eine Reihe von Vorteilen aus der folgenden, diese Regeln gewonnen werden:

  1. Einfache Wiederverwendung. Je länger und komplexer eine Funktion ist, spezialisiert desto mehr wird es auch ist, und daher desto weniger wahrscheinlich ist es, dass es wiederverwendet werden kann. Die umgekehrte Implikation ist, dass kürzere Funktionen allgemeineren neigen und daher leichter zu Wiederverwendung.

  2. Zuverlässigkeit des Codes. Es ist einfacher zu Grund, sich über die Richtigkeit des Codes, wenn sie weniger komplex ist.

  3. Es ist einfacher, Funktionen testen, wenn sie nur eine Sache zu tun. Auf diese Weise gibt es wenige Sonderfälle zu testen.

Update:

Incorporated Vorschlag von Kommentar.

Update 2:

einige nützliche Links hinzugefügt.

Ich denke, http://documentcloud.github.com/underscore/ sollte schön sein fit für das, was Sie brauchen - es bietet die wichtigsten Funktionen höherer Ordnung für die funktionale Programmierung und nicht hat clientseitige Funktionen für die DOM-Manipulation, die Sie nicht für Server-Seite benötigen. Obwohl ich habe Erfahrung nicht mit ihm.

Als Randbemerkung: IMHO primäre Funktion der funktionalen Programmierung ist Referenz Transparenz eine Funktion - Funktion Ergebnis hängt nur von seinen Parametern - Funktion hängt nicht von Änderungen an anderen Objekten und führt keine Änderung außer seinem Ergebniswert. Es macht es einfach zu Grund, sich über die Richtigkeit des Programms und sehr wertvoll für die (ggf.) vorhersehbarer Multithreading implementieren. Obwohl JavaScript nicht die Wette Sprache für FP ist - ich erwarte, dass Strukturen unveränderlichen Daten sehr teuer sein leistungsmäßig zu verwenden

.

So 2 Dinge, darauf hinzuweisen,

  1. In Ihrem ersten Beispiel Ihre Variablen nicht in den globalen Bereich undicht sein würden und ist so, wie es getan werden soll, niemals versuchen, Variablen zu verwenden, ohne sie also Test erklärt = ‚Daten‘ würden Daten veranlassen, in denen undicht globaler Bereich.

  2. Ihr zweites Beispiel ist korrekt als gut, bar1 und bar2 würden nur auf dem Foo-Objekt deklariert werden.

Dinge im Auge Versuch zu halten nicht zu übermäßigem Gebrauch Prototyping, da es zu jedem Objekt gilt, dass Sie erstellen, könnte dies sehr speicherintensiv sein, je nachdem, wie komplex Ihre Objekte sind.

Wenn Sie einen App-Entwicklungs-Framework suchen, haben einen Blick auf ExtJs . Ich persönlich denke, es würde passen perfekt in das Modell, das Sie gegen zu entwickeln versuchen. Denken Sie nur daran, wie sie ihre Lizenzmodell funktioniert, bevor in sie investiert zu werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top