2012-02-16 9 views
12

i respondió a una pregunta sobre el cierre aquí en lo que con esta muestra:creando objetos a partir del cierre de JS: ¿debería usar la palabra clave "nueva"?

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 usuario ha comentado mi respuesta diciendo:

Además, si su función devuelve de forma explícita un objeto que no es un buen practicar llamarlo con nueva porque eso es engañosa - si se utiliza la nueva era de esperar que el resultado sea una instancia de Constructor

generalmente creo objetos usando nuevo. pero ¿por qué es una mala práctica? parece que usar nuevas y no usar nuevas devuelve lo mismo. ¿Cuál es la forma correcta de crear objetos a partir de cierres?

Respuesta

11

No, no es lo mismo. Considerar cuando se utiliza 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.

Así que en lugar, crearlos mediante la asignación a this, posiblemente con una salvaguarda para evitar olvidados 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; 
} 

Mejor aún, utilizar el prototipo cuando sea posible:

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

me gusta esto: http://jsfiddle.net/DZTC8/1/ ambos devuelven lo mismo, con o sin el 'nuevo' – Joseph

+4

@Joseph: mi punto es que hace que' instanceof' actúe raro. El objeto devuelto es * no una instancia del constructor *, como esperaría un usuario, sino simplemente un Objeto. – Ryan

+0

+1 por "extraño". ¡Gracias! ahora entiendo la idea – Joseph

2

considerar el punto 4 de esta respuesta: What is the 'new' keyword in JavaScript?

"devuelve el objeto recién creado, a menos que la función constructora devuelve un no -primitivo valor. En este caso, ese valor no primitivo será devuelto ".

Así como la función C1 de la respuesta de minitech devuelve un objeto vacío, la variable c1 será ese objeto devuelto y no el creado por la declaración 'nueva'. Por lo tanto, no hay instancia de la función constructora.

Si intento devolver un valor primitivo desde la función constructora, mi tormenta web me dice: "Cuando se llama con new, este valor se perderá y el objeto se devolverá en su lugar".

Cuestiones relacionadas