2012-02-16 17 views
12

Odpowiedziałem jedno pytanie o zamknięciach tutaj w SO z tej próbki:tworzenie obiektów z zamykania JS: czy powinienem używać słowa kluczowego "nowy"?

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function(){ 
     alert('called from public method'); 
    }; 
    return { 
     publicProperty: 'im public', 
     publicMethod: function(){ 
      alert('called from public method'); 
     }, 
     getter: privateMethod 
    } 
} 

var myObj = new Constructor(); 

//public 
var pubProp = myObj.publicProperty; 
myObj.publicMethod(); 
myObj.getter(); 

//private - will cause errors 
myObj.privateProperty 
myObj.privateMethod 

użytkownik skomentował moją odpowiedź mówiąc:

Ponadto jeśli funkcja wyraźnie zwraca obiekt nie jest dobry praktykować to nazwać z nowego bo to jest mylące - w przypadku korzystania z nowego można się spodziewać wynikiem będzie instancją Konstruktora

Zwykle tworzę obiekty używając nowy. ale dlaczego nie jest to dobra praktyka? wydaje się, że używanie nowych i niewykorzystywanie nowych zwraca tę samą rzecz. jaki jest właściwy sposób tworzenia obiektów z zamknięć?

Odpowiedz

11

Nie, to nie to samo. Rozważenia przy użyciu instanceof:

function C1() { 
    return {}; 
} 

function C2() { 
} 

var c1 = new C1(); 
var c2 = new C2(); 
alert(c1 instanceof C1); // false; wha...? 
alert(c2 instanceof C2); // true, as you'd expect. 

Here's a demo.

Więc zamiast je tworzyć przez przypisanie do this, z możliwością zabezpieczenia, aby zapobiec zapomniane new s.

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function() { 
     alert('Called from private method'); 
    }; 

    this.publicProperty = "I'm public!"; 
    this.publicMethod = function() { 
     alert('Called from public method'); 
    }; 
    this.getter = privateMethod; 
} 

Jeszcze lepiej użyć prototyp gdy to możliwe:

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function() { 
     alert('Called from private method'); 
    }; 

    this.getter = privateMethod; 
} 

Constructor.prototype.publicProperty = "I'm public!"; 
Constructor.prototype.publicMethod = function() { 
    alert('Called from public method'); 
}; 
+0

na przykład: http://jsfiddle.net/DZTC8/1/ oba zwracają to samo, z lub bez 'nowego' – Joseph

+4

@Joseph: Chodzi mi o to, że sprawia, że' instanceof' działa dziwnie. Zwrócony obiekt * nie jest instancją konstruktora *, jak oczekiwałby użytkownik, ale raczej tylko Obiektem. – Ryan

+0

+1 dla "dziwnego". dzięki! teraz mam pomysł. – Joseph

2

Rozważmy punkt 4 od tej odpowiedzi: What is the 'new' keyword in JavaScript?

„zwraca nowo utworzony obiekt, chyba że funkcja konstruktora zwraca non -przykładowa wartość.W takim przypadku zwracana jest wartość nieprosta. "

Tak jak funkcja C1 z odpowiedzi minitech zwraca pusty obiekt, zmienna c1 będzie tym zwróconym obiektem, a nie obiektem utworzonym przez "nową" instrukcję. Dlatego też nie występuje żadna instancja funkcji konstruktora.

Jeśli spróbuję zwrócić prymitywną wartość z funkcji konstruktora, moja webstorm mówi mi: "Gdy zostanie wywołany z nowym, ta wartość zostanie utracona, a obiekt zostanie zwrócony zamiast tego."

Powiązane problemy