2011-08-19 21 views
8

Dziś widziałem schemat JavaScript, którego nigdy nie widziałem w całym moim życiu. Nie mogę powiedzieć, jaki jest cel używania tego wzoru. Wydaje mi się to niewłaściwe, ale chcę być trochę konserwatywny. Może to być jakiś niesamowity wzór, którego nigdy wcześniej nie widziałem.Definiowanie prototypowych metod wewnątrz konstruktora

Po pierwsze, nie jestem fanem dokonywania metod (jako uprzywilejowanych członków) wewnątrz konstruktora bez powodu. Powoduje to tworzenie funkcji za każdym razem, gdy tworzona jest instancja. Po drugie, w tym fragmencie kodu wywołuje on również prototypową nazwę "Pies", zamiast "tego". To sprawia, że ​​jestem bardzo zdezorientowany.

Ktoś wie, co w tym dobrego?

Dzięki! Grace

+1

To wydaje się niezwykle bezcelowe. Z tego, co wiem, obiekt prototypowy służy do dodawania właściwości do wszystkich instancji obiektu poza definicją. Ponieważ jest to w definicji, jest nieco zbędne. – mowwwalker

+0

Całkowicie się z tobą zgadzam. Dla mnie też to nie ma sensu. –

Odpowiedz

12

Jest to bardzo zły pomysł, z wielu powodów. Kilka z nich to:

  1. Dodanie metod do prototypu w konstruktorze spowoduje zastąpienie metody prototypowej dla wszystkich instancji za każdym razem, gdy zostanie utworzony nowy pies.
  2. Wywołanie Dog.prototype.bark() oznacza, że ​​this będzie Dog.prototype, a nie wystąpienie Dog, które może powodować poważne problemy.
  3. this.bark = function() { Dog.prototype.bark(); } to poważny WTF. Ponieważ this.bark będzie już oceniał prototypową metodę, dzięki czemu nie będzie to konieczne. A nazywanie tego w ten sposób niszczy naturalną wartość, o której mowa w punkcie 2.

Oto co jest powinno być:

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

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

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

Lub alternatywnie, bez prototypu w ogóle:

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

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

    this.makeSound(); 
}; 

bym nie ufa ten fragment twojego wcale.

+0

# 2: to samo, nawet jeśli kora jest inicjowana poza konstruktorem - metoda * this * jest ustawiana przez wywołanie. # 3: to samo co # 2 (* to * będzie * Dog.prototype *), ale funkcja nie używa * tego *, więc nie spowoduje to problemu w tym przypadku. – RobG

+0

Po co tworzyć 'this.makeSound = function() {}'? Ten przykład może wprowadzać w błąd bez wyjaśnienia. To nie zostanie ustawione na obiekcie prototypu, a funkcja jest duplikowana w pamięci dla każdego wystąpienia 'new Dog();'. Lepiej do 'Dog.prototype.makeSound = function() {}' – dman

2

Przepraszamy za bardzo późno odpowiedzi, ale jeśli naprawdę chcesz dodać prototypy wewnątrz konstruktora i nie trzeba go odtworzyć, gdy nowa instancja jest tworzona, można to zrobić:

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

    this.bark(); 
} 

nadal prawdopodobnie nie użyłbym tej metody, ale mam pewne przypadki, w których ta metoda była opcją podczas pracy z frameworkami innych firm (podejrzany rodzaj).

Powiązane problemy