2011-08-19 13 views
8

Oggi ho visto uno schema JavaScript che non ho mai visto in tutta la mia vita. Non posso dire lo scopo di usare questo modello. Mi sembra sbagliato, ma voglio essere un po 'prudente. Potrebbe essere uno schema fantastico che non ho mai visto prima.Definizione dei metodi prototipo all'interno del costruttore

function Dog() { 
    Dog.prototype.bark = function() { 
     alert('woof!'); 
    } 

    this.bark = function() { 
     Dog.prototype.bark(); 
    } 

    this.bark(); 
} 

In primo luogo, io non sono un ventilatore per rendere i metodi (come membri privilegiati) all'interno del costruttore per nessun motivo. Ciò causerebbe la creazione di funzioni ogni volta che viene creata un'istanza. In secondo luogo, in questo snippet di codice, chiama anche il nome del prototipo "Dog", anziché "this". Questo mi rende super confuso.

Qualcuno sa a che serve?

Grazie! Grace

+1

Sembra estremamente inutile. Da quello che so, l'oggetto prototipo viene utilizzato per aggiungere proprietà a tutte le istanze di un oggetto esterno alla definizione. Dal momento che è nella definizione, è un po 'ridondante. – mowwwalker

+0

Sono assolutamente d'accordo con te. Sembra inutile anche a me. –

risposta

12

Questa è una pessima idea, per un gran numero di motivi. Alcuni dei quali sono:

  1. L'aggiunta di metodi al prototipo nel costruttore causerà la sostituzione del metodo prototipo per tutte le istanze, ogni volta che si crea un'istanza di un nuovo cane.
  2. Chiamare Dog.prototype.bark() significa che this sarà Dog.prototype e non l'istanza di Dog, che può causare seri problemi.
  3. this.bark = function() { Dog.prototype.bark(); } è un serio WTF. Perché this.bark valuterà già il metodo prototipo rendendo questo non necessario. E chiamarlo in questo modo distrugge il valore naturale this, come menzionato in # 2.

Ecco ciò che è dovrebbe essere:

function Dog() { 
    this.makeSound(); 
}; 

Dog.prototype.bark = function() { 
    alert('woof'); 
}; 

Dog.prototype.makeSound = function() { 
    this.bark(); 
}; 

Oppure, in alternativa, senza il prototipo a tutti:

function Dog() { 
    this.bark = function() { 
    alert('woof'); 
    }; 

    this.makeSound = function() { 
    this.bark(); 
    }; 

    this.makeSound(); 
}; 

Non mi fiderei di questo frammento di vostro a tutti.

+0

# 2: è lo stesso anche se la corteccia è inizializzata al di fuori del costruttore - il metodo * questo * è impostato dalla chiamata. # 3: lo stesso di # 2 (* questo * sarà * Dog.prototype *), ma la funzione non usa * this * in modo che non causi un problema in questo caso. – RobG

+0

Perché dovresti rendere 'this.makeSound = function() {}'? Questo esempio potrebbe essere fuorviante senza chiarimenti. Questo non viene impostato sull'oggetto prototipo e la funzione viene duplicata in memoria per ogni istanza di 'new Dog();'. Meglio di 'Dog.prototype.makeSound = function() {}' – dman

2

Ci scusiamo per l'MOLTO ritardo di risposta, ma se si vuole veramente per aggiungere i prototipi all'interno del costruttore e non l'hanno ricreato ogni volta che viene creata una nuova istanza, si potrebbe fare questo:

function Dog() { 
    if (!Dog.prototype.bark) { 
     Dog.prototype = function() { 
      console.log('woof'); 
     } 
    } 

    this.bark(); 
} 

ho ancora probabilmente non userei questo metodo, ma ho alcuni casi in cui questo metodo era un'opzione quando si trattava di framework di terze parti (il tipo dubbia).

Problemi correlati