I super metodi in JavaScript sono limitati all'ereditarietà funzionale, come nel libro di Crockford?

2

In "JavaScript: The Good Parts" di Douglas Crockford, passa attraverso tre tipi di eredità: classica, prototipale e funzionale. Nella parte sull'ereditarietà funzionale scrive:

"The functional pattern also gives us a way to deal with super methods."

Quindi continua a implementare un metodo denominato "superiore" su tutti gli oggetti. Tuttavia, nel modo in cui usa il metodo superiore, sembra proprio che stia copiando il metodo sull'oggetto super per un uso successivo:

// crockford's code:
var coolcat = function(spec) {
    var that = cat(spec),
        super_get_name = that.superior('get_name');
    that.get_name = function (n) {
        return 'like ' + super_get_name() + ' baby';
    };
    return that;
};

Il metodo originale get_name è copiato in super_get_name . Non capisco cosa c'è di così speciale nell'ereditarietà funzionale che lo renda possibile. Non puoi farlo con l'ereditarietà classica o prototipale? Qual è la differenza tra il codice sopra e il codice qui sotto:

var CoolCat = function(name) {
    this.name = name;
}

CoolCat.prototype = new Cat();

CoolCat.prototype.super_get_name = CoolCat.prototype.get_name;
CoolCat.prototype.get_name = function (n) {
    return 'like ' + this.super_get_name() + ' baby';
};

Questo secondo esempio non fornisce l'accesso anche ai "metodi super"?

    
posta kindohm 20.01.2012 - 04:40
fonte

3 risposte

4
var coolcat = function(spec) {
    var that = cat(spec),
        super_get_name = that.superior('get_name');

    that.get_name = function (n) {
        return 'like ' + super_get_name() + ' baby';
    };

    return that;
};

var cat = coolcat({ ... });

Può anche essere fatto con i prototipi

var CoolCat = {
    constructor: function () {
        Cat.constructor.apply(this, arguments);
        return this;
    },
    getName: function () {
        return 'like ' + Cat.getName() + ' baby';
    }
};

var cat = Object.create(CoolCat).constructor({ ... });

Ovviamente la differenza principale qui è che non stai creando due nuove funzioni ogni volta che invochi coolcat . coolcat crea una nuova funzione per get_name e una nuova funzione per super_get_name e fondamentalmente spreca la memoria a sinistra ea destra.

Si potrebbe obiettare che coolcat ha privacy ma non perché qualcuno possa chiamare cat({}).superior('get_name'); e ottenere il tuo metodo "privato".

Ovviamente se si desidera la privacy e i prototipi che sono perfettamente possibili , utilizzando klass macro come mostrato nell'articolo

var Cat = klass(function (privates) {
    return {
        constructor: function (name) {
            privates(this).name = name; 
        },
        getName: function () {
            return privates(this).name;
        }
    };
});

var CoolCat = klass(Cat, function (privates, $super) {
    return {
        constructor: function () {
            $super.constructor.apply(this, arguments);
        },
        getName: function () {
            return 'like ' + $super.getName.call(this) + ' baby';
        }
    };  
});

var cat = new CoolCat("someName");
console.log(cat.getName());

Esempio dal vivo

Qui otteniamo sia l'ereditarietà della privacy che quella super class in modo "elegante".

In questo modo elegante non si ha il sovraccarico di chiusura di più funzioni per oggetto (aggiungiamo ancora una singola chiusura per oggetto per la funzione privates ) e anche il normale OO prototipo per solo funziona.

    
risposta data 20.01.2012 - 08:37
fonte
1

È una grande domanda su un grande libro. Il libro prende un paio di letture per essere completamente digerito. Mi sono imbattuto in questa domanda, mentre ricercavo alcune sottigliezze di javascript basate sul libro. Fondamentalmente ho avuto la stessa domanda, ma dopo aver riflettuto, penso che entrambe le risposte di kindohm e Raynos siano incomplete.

Penso che kindohm abbia ragione che il motivo sia legato alla privacy e all'accesso, ma non è perché il metodo super è privato dell'approccio funzionale, come giustamente fa notare Raynos.

D'altra parte la risposta di Raynos sembra quasi che ci sia un errore nel libro, dato che Raynos offre una soluzione diversa da quella che il libro dà.

Ma penso che la soluzione fornita nel libro abbia ancora il suo posto. Penso che il motivo / giustificazione principale sia nel paragrafo che precede il codice per il metodo "superiore":

The function will invoke the original method even if the property is changed

Questo è la differenza tra l'approccio funzionale e l'approccio pseudo-classico che viene fornito come esempio nella domanda originale.

Non è una privacy perfetta ma offre un ulteriore livello di isolamento.

    
risposta data 04.06.2014 - 03:43
fonte
-1

La risposta è pubblica o privata. Con l'approccio funzionale, i super metodi possono essere mantenuti privati dell'oggetto. Il secondo esempio (utilizzando il prototipo) espone pubblicamente il metodo super.

    
risposta data 20.01.2012 - 05:04
fonte

Leggi altre domande sui tag