2017-05-22 2 views
4

Ich versuche, meinen Kopf um reine Funktionen zu wickeln, aber ich bin mir nicht sicher, ob ich es wirklich verstehe. Ich weiß, dass reine Funktionen den externen Zustand nicht mutieren sollten, und es sollte jedes Mal die gleiche Ausgabe zurückgeben, solange es die gleiche Eingabe hat.Reine Funktionen bei der Arbeit mit DOM Manipulation

Ich weiß, dass beispielsweise diese Funktion unrein ist, weil es den Warenkorb Variable mutiert, die anderen Teile des Programms verwenden können:

const addToCart = (cart, item) => { 
    cart.push(item); 
    return cart; 
}; 

Die gleiche Funktion in einem reinen Zustand:

const addToCart = (cart, item) => { 
    const newCart = lodash.cloneDeep(cart); 
    newCart.push(item); 
    return newCart; 
}; 

Das macht für mich Sinn. Ich habe gelernt, dass reine Funktionen immer etwas zurückgeben sollten.

Allerdings arbeite ich an ein paar Sachen, die mir die HTML5-Canvas-Element zu verwenden, erfordert, und ich habe diese Funktion, die die Leinwand löscht:

function clearCanvas(canvas) { 
    canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); 
} 

Wie kann ich die obige Funktion rein machen? Mir ist klar, dass es unrein ist, weil es nichts zurückgibt und auch den Zustand der Canvas-Variable verändert. Ist DOM-Manipulation von Natur aus unrein?

Jede Hilfe würde geschätzt :)

Antwort

0

DOM-Manipulation ist unrein. Sie können die Leinwand nicht "rein" löschen.

Alles, was den Systemzustand verändert oder mit der Außenwelt interagiert, soll side effects sein, und in einer rein funktionalen Programmierumgebung sollen Nebenwirkungen vermieden werden.

Die DOM-Manipulation macht jedoch beide deutlich; Das Löschen des Canvas ist eine Statusänderung (nicht gecleart), und der Benutzer kann diese Änderung sehen.


Sie können einen tieferen Einblick in functional programming haben, was zu sein scheint, was Sie mit Ihrem reinen/unreinen Funktion Ansatz zu erreichen versuchen.

Ziel der funktionalen Programmierung ist es, den Zustand nicht zu ändern, so dass beispielsweise ein Programm ein Objekt nicht ändert, während ein anderes Programm damit arbeitet, was zu unerwarteten und unerwünschten Ergebnissen führen kann.

+0

Dank für die Beantwortung danken. Das macht Sinn. –

+0

@OlavGundersen kein Problem! Es ist eine vernünftige Frage zu stellen und es ist gut, dass Sie versuchen, auf diese Weise zu programmieren, es ist eine gute Angewohnheit, so schnell wie möglich zu lernen. – theonlygusti

+0

Downvote warum? Ich selbst lerne immer noch, wenn ich etwas falsches gesagt habe, lass es mich wissen, wir sind alle hier um zu lernen. Ein unerklärter Downvote ist wertlos. – theonlygusti

0

es über die Funktion Programmierparadigma

function clearCanvas(canvas) { 
    const imgData = canvas.getContext('2d').getImageData(0,0,canvas.width,canvas.height); 
    new Uint32Array(imgData.data.buffer).set(0); 
    return data; 
} 

canvas.getContext('2d').setImageData(clearCanvas(canvas),0,0); 

keine Nebenwirkungen zu tun und Sie die gleichen Daten für die gleichen Argumente zurück.

Aber funktionale Programmierung ist ein defensiver Stil, der davon ausgeht, dass Code gefährlich ist und dass die Gefahren isoliert werden müssen. Es ist daher sehr ressourcenhungrig und langsam und überhaupt nicht für performanten Code geeignet.

+0

Nur die Funktion, die Sie bereitstellen, ist nebenwirkungsfrei, der eigentliche Prozess, nach dem das OP fragt ("Ist DOM-Manipulation von Natur aus unrein?") Ist nicht (wie Sie selbst in Ihrem Code-Ausschnitt zeigen) – theonlygusti

+0

@theonlygusti Die Absurdität von Funktionale Programmierung kann innerhalb ihrer Paradigma-Beschränkungen mit dem DOM interagieren, dies geschieht indirekt über Duplizierung (crazy yes). Aber nebenwirkungsfrei ist nur ein abstraktes Ideal, jeder verwendete RAM kommt von einem globalen Speicher und/oder Stack (was jede Funktion tun muss). Aus diesem Grund können Sie in JS keine reinen Funktionen schreiben. – Blindman67

+0

Ich verstehe nicht, was Sie gerade versucht haben zu sagen ... – theonlygusti

2

der IO Monade

Sie könnten im IO-Monade interessiert sein - im Wesentlichen IO enthält ein thunk oder ein fauler-Funktion, die nur läuft, wenn wir runIO nennen. Noch wichtiger ist, dass wir Dinge, die in IO und map abgefüllt sind, eine gewöhnliche Funktion haben, die es uns erlaubt, mit dem enthaltenen Wert zu arbeiten.

Für eine gute Lese- und anderen IO-Implementierung finden Sie Chapter 9: Monadic Onions von Brian Lonsdorf Buch


kleine Demo

// IO :: (void -> a) -> IO a 
 
const IO = f => ({ 
 
    // runIO :: void -> a 
 
    runIO: f, 
 
    // map :: IO a => (a -> b) -> IO b 
 
    map: g => 
 
    IO(() => g(f())), 
 
    // chain :: IO a => (a -> IO b) -> IO b 
 
    chain: g => 
 
    IO(g(f()).runIO) 
 
}) 
 

 
// IO.of :: a -> IO a 
 
IO.of = x => IO(() => x) 
 

 
// log :: String -> a -> IO a 
 
const log = label => x => 
 
    IO(() => (console.log(label, x), x)) 
 

 
// $ :: String -> IO HTMLElement 
 
const $ = x => 
 
    IO(() => document.querySelector(x)) 
 

 
// getText :: HTMLElement -> String 
 
const getText = e => 
 
    e.textContent 
 

 
// main :: String -> IO String 
 
const main = selector => 
 
    $(selector) 
 
    .map(getText) 
 
    .chain(log('A')) 
 
    .map(s => s.toUpperCase()) 
 
    .chain(log('B')) 
 
    .runIO() 
 

 
main('title') 
 
// A hello world 
 
// B HELLO WORLD
<title>hello world</title>

+0

Dieser Kauderwelsch ist unlesbar – avalanche1

+0

@ Avalanche1, das ist kaum eine Möglichkeit, auf etwas zu antworten, das Sie nicht verstehen - wenn Sie spezifische Fragen haben, bin ich glücklich, sie zu beantworten. – naomik

+0

Ja, es tut mir leid) Dieses Zeug ist nichts für Amateure – avalanche1