Quali problemi di programmazione comuni sono meglio risolti utilizzando prototipi e chiusure?

8

Per quanto comprenda entrambi i concetti, non riesco a vedere come posso approfittare delle chiusure e dei prototipi di JavaScript a parte per usarli per creare blocchi istanziabili e / o incapsulati di classe (che sembra più una soluzione alternativa che una risorsa per me)

Altre funzioni di JS come le funzioni-come-valori o la valutazione logica dei non-booleani sono molto più facili da innamorare di ...

Quali problemi di programmazione comuni sono meglio risolti utilizzando l'ereditarietà e le chiusure propotiche?

    
posta vemv 21.11.2011 - 14:00
fonte

3 risposte

5
  1. Le chiusure sono ciò che rende utili le funzioni come valori. Quando si passa la funzione, quasi certamente ne hai bisogno per prendere un po 'di contesto. Che è esattamente ciò che fanno le chiusure.

  2. I prototipi sono solo una versione più semplice dell'ereditarietà delle classi. Invece di avere istanze e classi (rappresentate da tipi speciali di istanze in linguaggi dinamici), si hanno solo istanze e il prototipo è la classe (ed è il prototipo è la classe base). Quindi fondamentalmente risolvono gli stessi problemi, solo i prototipi sono più facili da implementare (ecco perché JavaScript li ha scelti), un po 'più difficili da usare (beh, solo la mancanza di zucchero sintattico) e, nel bene e nel male, più facili da abusare.

risposta data 21.11.2011 - 14:54
fonte
4

Le chiusure non risolvono problemi di programmazione che non possono essere risolti senza di essi. Tuttavia, questo può essere detto per qualsiasi caratteristica linguistica non necessaria per la completezza di Turing, quindi non significa molto.

Pensa a come devi riscrivere qualsiasi codice che usi una chiusura, per non usare una chiusura. Probabilmente daresti la funzione con le proprietà extra di chiusura in modo da poter mantenere il suo stato tra le chiamate. Il che equivarrebbe a copiare le variabili che sono già in scope in proprietà con lo stesso nome sulla funzione, quindi sarebbe il tipo di esercizio di digitazione insensata che ti fa venir voglia di urlare sullo schermo "perché non può lo stupido compilatore ( interprete, qualunque cosa) capirlo? " Questo è ciò che le chiusure sono, lo stupido compilatore è abbastanza intelligente da capirlo.

    
risposta data 21.11.2011 - 23:14
fonte
2

Le chiusure sono grandi per la logica asincrona.

Riguarda principalmente l'organizzazione del codice per me. Avere un sacco di funzioni locali per suddividere ciò che sta facendo il codice è bello.

create: function _create(post, cb) {
    // cache the object reference
    var that = this;

    function handleAll(err, data) {
        var rows = data.rows;

        var id = rows.reduce(function(memo, item) {
            var id = +item.id.split(":")[1];
            return id > memo ? id : memo;
        }, 0);
        id++;


        var obj = {
            title: post.title,
            content: post.content,
            id: id,
            // refer to the object through the closure
            _id: that.prefix + id,
            datetime: Date.now(),
            type: "post"
        }

        PostModel.insert(obj, handleInsert);
    }

    // this function doesn't use the closure at all.
    function handleInsert(err, post) {
        PostModel.get(post.id, handleGet);
    }

    // this function references cb and that from the closure
    function handleGet(err, post) {
        cb(null, that.make(post));
    }

    PostModel.all(handleAll);
}

Ecco un altro esempio di chiusura

var cachedRead = (function() {
    // bind cache variable to the readFile function
    var cache = {};

    function readFile(name, cb) {
        // reference cache
        var file = cache[name];
        if (file) {
            return cb(null, file);
        }

        fs.readFile(name, function(err, file) {
            if (file) cache[name] = file;
            cb.apply(this, arguments);
        });
    }

    return readFile;
})();

E un altro esempio

create: function _create(uri, cb, sync) {
    // close over count
    var count = 3;

    // next only fires cb if called three times
    function next() {
        count--;
        // close over cb
        count === 0 && cb(null);
    }

    // close over cb and next
    function errorHandler(err, func) {
        err ? cb(err) : next();
    }

    // close over cb and next
    function swallowFileDoesNotExist(err, func) {
        if (err && err.message.indexOf("No such file") === -1) {
            return cb(err);
        }
        next();
    }

    this.createJavaScript(uri, swallowFileDoesNotExist, sync)

    this.createDocumentFragment(uri, errorHandler, sync);

    this.createCSS(uri, swallowFileDoesNotExist, sync);
},

L'alternativa all'utilizzo delle chiusure è la conversione della variabile in funzioni usando f.bind(null, curriedVariable) .

Generalmente, tuttavia, la logica di programmazione asincrona utilizza i callback e lo stato di manipolazione nei callback fa affidamento su operazioni di curriculum o chiusure. personalmente preferisco le chiusure.

Per quanto riguarda gli usi dell'ereditarietà prototipica, consente OO? L'eredità prototipica deve davvero fare di più che essere considerata "utile". È uno strumento di ereditarietà, consente l'ereditarietà, è abbastanza utile.

    
risposta data 21.11.2011 - 14:48
fonte

Leggi altre domande sui tag