Składnia OOP w js i używanie prototypu

Autor:richard retyi

Jaka jest różnica między tymi fragmentami kodu, a która jest preferowana w jakich przypadkach?


A
 

function Obj() {}
Obj.method = function(type) {
    return this.coords[type];
};
var obj = new Obj(),
    current = obj.method(type);

 

B
 
function Obj() {}
Obj.prototype.method = function(type) {
    return this.coords[type];
};
var obj = new Obj(),
    current = obj.method(type);



C
 
var obj = {
    method : function(type) {
        return this.coords[type];
    }
},
    current = obj.method(type);



D
 
function objMethod(type){
    return this.coords[type];
}
var obj = {
    method : objMethod
},
    current = obj.method(type);


dodano @ 1732:
E
 
function Obj() {
    this.method = function(type) {
        return this.coords[type];
    };
}
var obj = new Obj(),
    current = obj.method(type);

Odpowiedzi

barbara grossman
JS jest językiem zorientowanym obiektowo, ale nie ma w nim żadnych klas, są one zastępowane przez konstruktory obiektów, więc zamiast zwykłego dziedziczenia przez klasy istnieje dziedziczenie poprzez prototypy. Tj instancja klasy dziedziczy swoje właściwości i metody, które są w jej prototypie.
Konstruktor klasy (funkcja Obj () {}) jest funkcją, w której opisane są właściwości i metody prototypu, dlatego wszystkie będą dostępne podczas tworzenia instancji.

W przykładzie A konstruktor jest pusty, a obiekt Obj.method przypisuje metodę do obiektu, a nie do jego prototypu, więc nie będzie dziedziczony przez obj = new Obj (). Ten przykład nie działa.

Przykład B jest poprawny, tutaj metoda metody jest dodawana do prototypu i będzie dziedziczona przez wszystkie instancje.

Przykład C jest najczęściej używany, gdy chcesz zaimplementować singleton lub przestrzeń nazw, ponieważ jest to prosty skrót bez konstruktora, nie możesz go dziedziczyć. W rzeczywistości nie jest to obiekt w rozumieniu OOP, ale po prostu tablica asocjacyjna, która może zawierać dowolne dane, metody i inne obiekty.

Przykład D jest podobny do przykładu C, tylko jego właściwość method zawiera łącze do funkcji zewnętrznej. Ten przykład może być użyty, gdy musisz wywołać funkcję z zewnętrznej biblioteki.

Przykład E jest poprawny i podobny do przykładu B, z tą różnicą, że dziedziczona metoda jest określona natychmiast w konstruktorze, a nie przez prototyp.
Odpowiedzi:
Bardzo dobra odpowiedź, wszystko jest szczegółowe i wspaniałe, dzięki! - rachael
gallagher308comcast net
Tak naprawdę, różnica między B i E jest, w przypadku E, kiedy metoda jest zadeklarowana bezpośrednio w konstruktorze, będzie miała dostęp do prywatnych zmiennych i metod, są to tak zwane metody uprzywilejowane, ale w przykładzie B nie ma możliwości pracy z prywatnymi danymi.
O tym właśnie mówię:
var MyClass = function() {
  // Приватные атрибуты
  var _a, _b;
  // Приватный метод
  function _myPrivate(isbn) {
  } 
  // публичный привилегированный метод
  this.MyPublicPlus = function() {

  };
}

// публичный непривилегированный метод.
MyClass.prototype = {
  MyPublic: function() {
  }
};

Metoda MyPublicPlus będzie miała dostęp do _a, _b i _myPrivate (), ale MyPublic nie będzie ...
nils samuels
Ogólnie rzecz biorąc, wszyscy zainteresowani działaniem Javascript, radzę przeczytać www.crockford.com/javascript/javascript.html
amelia wimmer
zostanie dodany do prototypu.
Jeśli go nie używasz, możesz tworzyć prywatne właściwości i metody, które będą dostępne z innych metod instancji, ale nie bezpośrednio.

 
function Obj() {
    var privateMethod = function(x) {
        return x;
    }
    this.publicMethod = function(x) {
      return privateMethod(x); 
   }
}
var obj = new Obj();
obj.privateMethod(1); // -> вызовет ошибку
obj.publicMethod(1); // -> вернет '1'

Odpowiedzi:
W przykładzie E metoda nie zostanie dodana do prototypu.

Porównaj:
function Obj(){};
Obj.prototype.fnc = function(){alert(5)};
obj = new Obj();
obj.fnc(); // 5
Obj.prototype.fnc = function(){alert(51)};
obj.fnc(); //51


 

function Obj(){
  this.fnc = function(){
    alert(5);
  }
};
obj = new Obj();
obj.fnc && obj.fnc();
Obj.prototype.fnc = function(){alert(52)};
obj.fnc();


 javascript.ru/ecma/part13#a-13.2.2

Zatem właściwości i metody zdefiniowane w konstruktorze nie będą wchodzić w prototyp i będą istniały oddzielnie dla każdego obiektu (w przeciwieństwie do prototypu, który jest wspólny dla wszystkich obiektów generowanych przez ten konstruktor). Tj Opcja E jest droższa pod względem pamięci, w przeciwieństwie do opcji B.

 s43.radikal.ru/i101/1009/49/65ba9a6115f8.jpg
Wykres zużycia pamięci. Pierwsze uderzenie to 1 000 000 wystąpień klasy, w której 3 metody są określone wewnątrz konstruktora. Drugi kopiec to 1 000 000 kopii, w których te same 3 metody są określone w prototypie. - jamie gavitt
anthony cast
A, B, E - jest konstruktor Obj. w przypadku wywołania funkcji przez new, konstruktor będzie pracował z nowym obiektem, w przypadku wywołania za pośrednictwem wywołania / apply, rozwinie określony obiekt. tj. jedna funkcja może być zarówno "klasą", jak i "domieszką".
C, D - tworzenie obiektu przez "ręce", bez konstruktora. w D funkcja jest renderowana i nazwana - zakłada się, że może być używana nie tylko jako metoda.
B - stosuje się prototypowanie. każdy obiekt ma prototyp *, co oznacza, że ​​nieproste typy danych (funkcje, tablice, daty, obiekty) będą przechowywane tylko w prototypie, oszczędzając pamięć i czas na "tworzenie" obiektu, ale spowalniając późniejsze prace z obiektem ze względu na "Wspólne" dane / metody będą dostępne za pośrednictwem prototypów (łańcuchowych).
A - funkcja jest również obiektem, a "metoda" jest oznaczona właśnie w obiekcie funkcji. obiekt funkcji (-konstruktora) nie jest w żaden sposób powiązany z modyfikowanymi obiektami. Miejsce projektanta to dobre miejsce na śmieci, których nie chcesz rozpowszechniać na wszystkich "kopiach".

kilka punktów do zrealizowania:

  375915423
  375915423

przeczytaj:
 link
* dklab.ru/chicken/nablas/40.html - .constructor.prototype; gdzieś znalazło się również wyjaśnienie potrzeby umieszczenia prototypowego konktruktora w "bieżącej" klasie
 www.webreference.com/js/column26/apply.html - zastosuj zanieczyszczenia
Polecam również zgłoszenie google do wszystkich typów, instanceof, hasOwnProperty, isPrototypeOf, itp.

W jakiej proporcji używać prototypów, zamknięć, zanieczyszczeń i innych dekoratorów - to wyłącznie twój styl.
Wino, gry i otwarty sterownik ATI? :: Zakładki Chrome i Google :: Poinformuj dobre książki na temat Python'u koncentruje się na tworzeniu stron internetowych :: Jak artykuły w Wikipedii są powiązane z GoogleMaps :: Doradztwo programowi pomiaru czasu
Zostaw odpowiedź
Linki