2012-05-22 19 views
12

¿Es problemático hacer referencia a un objeto literal dentro de una función que es parte de ese mismo literal? Parece funcionar bien, pero quiero asegurarme de que no haya otras implicaciones.Javascript: referencia literal del objeto en la función de la propia clave en lugar de 'esto'

He aquí un ejemplo de lo que estoy hablando:

en lugar de:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); 

usando:

var obj = { 
    key1: "it", 
    key2: function(){return obj.key1 + " works!"} 
}; 
alert(obj.key2()); 

Respuesta

16

Ambos pueden ser problemáticos.

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works!" } 
}; 
var func = obj.key2; 
alert(func()); // error 

Cuando func no se llama como un método de obj, this puede hacer referencia a otra cosa (aquí: el objeto global "window").

var obj = { 
    key1: "it", 
    key2: function(){ return obj.key1 + " works!" } 
}; 
var newref = obj; 
obj = { key1: "something else"; }; 
alert(newref.key2()); // "something else works" 

Aquí tenemos acceso al objeto de otra referencia, aunque el obj en la función ahora pueden apuntar a algún otro objeto.

Así que tendrás que elegir qué caso es más probable. Si realmente quieres para que sea seguro, se puede utilizar un cierre donde está en el ámbito obj y no se puede cambiar:

var obj = (function(){ 
    var local = { 
     key1: "it", 
     key2: function(){ return local.key1 + " works always!" } 
    }; 
    return local; 
})(); 

o bind() la función del objeto:

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works always!" } 
} 
obj.key2 = obj.key2.bind(obj); 
0

No creo que existen implicaciones de la parte superior de mi cabeza Sólo asegúrese de que accidentalmente no hace esto en cualquier punto:

var obj = { 
    key1: "it", 
    key2: key1 + " works!" 
} 

ya que esto causará un error. Aparte de eso, ¡deberías ser bueno para ir!

1

Habrá una diferencia en el enlace de alcance variable. Si modifica obj tarde, modificará el valor de retorno de clave2:

var newobj = obj; 
obj = { key1: "new" }; 
alert(newobj.key2()); 

Ahora alertas "! Nuevas obras", porque a pesar de que está llamando key2() en el objeto original (que es ahora newobj), la la referencia a obj.key1 ahora se une al valor de la nueva instancia obj. El uso de this evita que esto suceda.

Demostración: http://jsfiddle.net/m6CU3/

1

Si no está utilizando el objeto prototipo, que CZN ir así. como todas las instancias de su objeto devolverán el valor de la instancia obj ...

1

o cualquier Ambas técnicas pueden aplicarse dependiendo de la situación.

El valor de this dentro de una función depende de cómo se llamó a la función.Si se llama a una función como la propiedad de un objeto como éste:

obj.key2(); 
//or 
obj["key2"](); 

Entonces this habrá dicho objeto. Si el objeto se creó a través de un objeto literal u otro medio no es relevante.

Pero puede usar .call() o .apply() para llamar a una función y establecer explícitamente this en algún otro objeto.

Ten en cuenta también:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); // alerts "it works!" 

var func = obj.key2; 
alert(func())​;  // alerts "undefined works!" 

Soy la creación de func hacer referencia a la misma función que obj.key2, pero que calificó como func() hace no conjunto this a obj.

Para obtener más información, eche un vistazo a what MDN has to say about this.

Cuestiones relacionadas