creare oggetti dalla chiusura di JS: dovrei usare la parola chiave “nuova”?

Ho risposto a una domanda sulle chiusure qui in SO con questo esempio:

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 

un utente ha commentato la mia risposta dicendo:

Inoltre, se la tua funzione restituisce esplicitamente un object, non è una buona pratica chiamarlo con new perché è fuorviante – se si utilizza new ti aspetti che il risultato sia un’istanza di Constructor

di solito creo oggetti usando nuovi . ma perché non è una buona pratica ? sembra che usare la nuova e non usare i nuovi ritorni sia la stessa cosa. qual è il modo corretto di creare oggetti dalle chiusure?

No, non è la stessa cosa. Considerare quando si usa 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. 

Ecco una demo.

Quindi, invece, crearli assegnandoli a this , possibilmente con una salvaguardia per prevenire new s dimenticati.

 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; } 

Ancora meglio, usa il prototipo quando ansible:

 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'); }; 

Considerare il punto 4 da questa risposta: qual è la parola chiave “nuova” in JavaScript?

“Restituisce l’object appena creato, a meno che la funzione di costruzione non restituisca un valore non primitivo, in questo caso verrà restituito il valore non primitivo.”

Quindi, dato che la funzione C1 della risposta di minitech restituisce un object vuoto, la variabile c1 sarà quell’object restituito e non quello creato dalla “nuova” istruzione. Quindi nessuna istanza della funzione di costruzione.

Se provo a restituire un valore primitivo dalla funzione di costruzione, la mia webstorm mi dice: “Quando viene chiamato con new, questo valore andrà perso e l’object verrà restituito”.