2012-11-19 14 views
6

Ok I dovrebbe conoscere la risposta a questo, ma per qualche motivo non ho mai veramente capito o ho avuto la necessità di conoscere veramente JavaScript.JavaScript fondamentale OO

La mia domanda è: guardando i seguenti esempi di codice sono corretto nella mia comprensione o mi mancano alcune informazioni.


Esempio 1

Necessità di istanziare la funzione (o classe) al fine di utilizzare il metodo IsOld, e una copia separata della funzione IsOld verrà creata per ogni istanza.

function MyClass1() { 
    this.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 
} 

// sample usage 
var m1 = new MyClass1(); 
console.log(m1.IsOld(34)); 

Esempio 2

bisogno di istanziare ma a differenza MyClass1 il motore di script non avrà bisogno di creare una copia del metodo IsOld per ogni istanza di classe.

var MyClass2 = (function() { 
    function MyClass2() { } 

    MyClass2.prototype.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 

    return MyClass2; 
})(); 

// sample usage 
var m2 = new MyClass2(); 
console.log(m2.IsOld(34)); 

Esempio 3

Non c'è bisogno di istanziare la funzione/classe per accedere al metodo IsOld. Una singola istanza del metodo IsOld viene utilizzata in tutte le chiamate.

var MyClass3 = { 
    IsOld: function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }, 
}; 

// sample uage 
console.log(MyClass3.IsOld(34)); 

Nota: sto indovinando ci sono un sacco di simili interrogativi/risposte qui su SO, ma per qualche motivo non riusciva a trovare uno che in realtà aveva senso per me.

+1

tuo la comprensione è corretta, sebbene il secondo esempio sia inutilmente complesso con l'espressione di funzione immediata IMO. –

+0

@FelixKling: In realtà, questo è il modo in cui CoffeeScript compila le sue classi: http://coffeescript.org/#try:class%20Auto – Amberlamps

risposta

2

Le tue interpretazioni sembrano corrette.

Se per "necessità di creare un'istanza" si intende l'uso della parola chiave "nuova", vorrei aggiungere qualcosa qui.

In JavaScript l'uso della nuova parola chiave non è l'unico modo per creare nuove istanze. (Modificato come da commenti) E qualsiasi funzione può fungere da funzione di costruzione.

Quando si utilizza parola chiave 'nuovo' seguito da qualsiasi funzione (dire 'x') ciò che fa è

  1. Crea nuovo oggetto (dire 'y'), e impostare il prototipo della funzione di x come il nuovo prototipo di oggetti (y).
  2. Chiama la funzione 'x' nel contesto degli oggetti appena creati y, questo si riferirebbe a questo nuovo oggetto 'y' all'interno della funzione 'x'
  3. Se la funzione non restituisce un oggetto, restituisce il nuovo oggetto 'x' creato dal nuovo operatore come risultato della nuova espressione.

Ecco una buona fonte per voi per imparare JavaScript da Douglas Crockford (http://javascript.crockford.com/)

Quindi, se siete preoccupati per la memoria (si dovrebbe essere), utilizzare una funzione di costruzione, e aggiungere tutte le metodi comuni per il prototipo di funzioni come hai fatto nell'esempio 2.

Quindi tutti questi metodi saranno ereditati da tutti gli oggetti creati utilizzando questa funzione come costruttore. Tuttavia, come accennato prima penso Campione 2 può essere più semplice:

var MyClass2 = function MyClass2() { }; 

MyClass2.prototype.IsOld = function (age) { 
    if (age > 40) { 
     return true; 
    } 
    return false; 
}; 

var obj = new MyClass2(); 
+1

La nuova parola chiave non è opzionale per i casi in cui è stata utilizzata qui. – nnnnnn

+0

Sì, sono d'accordo, poiché queste funzioni non creano oggetti al loro interno. Ciò che intendevo dire era l'uso di "nuovo" non è obbligatorio per creare nuovi oggetti. – BuddhiP

1

Per quanto ne so, hai ragione in tutti e 3 i casi.

  1. Ha bisogno di istanziare IsOld e per ogni istanza verrà creata una nuova funzione.
  2. Non è necessario creare un'istanza IsOld come nel prototipo.
  3. Non è necessario creare un'istanza IsOld poiché MyClass3 è già un'istanza (un oggetto non è una funzione).
1

Mi sembra che ci sia stato un malinteso riguardo alla struttura della classe e la natura dinamica di Javascript: per tutti i casi presentati, ogni istanza della "classe" crea una nuova funzione senza nome.

Se volete dichiarare "classi" in un modo più tradizionale (come C++ o Java), è meglio:

1) definire le funzioni:

function MyClass_IsOld(age) { 
    return (age > 40); 
} 

2) creare le "classe" e definire il suo prototipo:

function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

3) Utilizzare la classe:

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37)); 

Se si desidera utilizzare il "metodo", come una normale funzione, dichiarare globalmente, come:

function MyClass_IsOld(age) { 
    return (age > 40); 
} 
function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // use as a function 

Se si desidera nascondere i dettagli di implementazione, creare una chiusura:

var MyClass = (function() { 
    function _MyClass_IsOld(age) { 
     return (age > 40); 
    } 
    function _MyClass() { /* put any instance constructor logic here */ }; 
    _MyClass.prototype.IsOld = _MyClass_IsOld; // use as a method 

    return _MyClass; 
})(); 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // ERROR: undefined function 
+0

_ "nel secondo esempio, a proposito, il prototipo viene sovrascritto per ogni istanza creata." _ - No non lo è, viene creato una volta all'interno dell'espressione della funzione immediatamente richiamata che restituisce il costruttore 'MyClass2()'. Un altro aspetto ... – nnnnnn

+0

Sì, avevi ragione, @nnnnnn, avevo trascurato il costruttore di classi e mi confondevo con il costruttore di istanze. Questo è, a proposito, come uso per implementare le classi su Javascript. Grazie per il "testa a testa". –