objetos - Llamar a una función en la declaración de notación literal de objeto javascript
recorrer array de objetos javascript (5)
Aquí hay otro buen enfoque, creo.
window.onload = function(){
var animBtn = document.getElementById(''startAnim'');
animBtn.addEventListener(''click'', Animation.init, false);
};
var Animation = {
init: function(){
Animation.doTheMove(); // This will work, but your IDE may complain...
},
doTheMove: function(){
alert(''Animation!'');
}
};
Estoy tratando de llamar a una función dentro de un objeto literal que creé, usando la palabra clave this
. Pero aparece un error que dice this.doTheMove()
no es una función:
window.onload = function(){
var animBtn = document.getElementById(''startAnim'');
animBtn.addEventListener(''click'', Animation.init, false);
}
var Animation = {
init: function(){
this.doTheMove(); // I''m calling the function here, but it gives an error.
},
doTheMove: function(){
alert(''Animation!'');
}
}
¿Por qué hay un error?
Es posible que desee utilizar el enfoque de base de portotipos:
// generate a prototype object which can be instantiated
var Animation = function() { this.doTheMove(); }
Animation.prototype.doTheMove = function() {
// if the object has only one method, the whole code could be moved to
// var Animation = function() {...} above
alert(''Animation!'');
}
Animation.prototype.otherMethod = function(param1, param2) {
// ...
}
// run the code onload
window.onload = function(){
var animBtn = document.getElementById(''startAnim'');
animBtn.addEventListener(''click'', new Animation(), false);
}
Seis años y medio más tarde, pero espero que mi respuesta también pueda proporcionar alguna información para los desarrolladores actuales y futuros.
Tiendo a codificar el uso de objetos literales dentro de funciones autodefinidas, y la pregunta original publicada funciona bien si se agrega otra función autoejecutable junto con una declaración de prueba y captura.
Es muy importante señalar que se trata de alcance y contexto.
Corrija los inconvenientes o proporcione sugerencias más efectivas de usar este método.
(function() {
console.log(this); // window object
var animation = {
init: function() {
this.doTheMove();
},
doTheMove: function() {
alert("Animation");
console.log(animation); // animation object
}
};
(function() {
try {
console.log("animation.init"); // animation.init function
animation.init();
} catch(e) {
console.log("Error is: " + e);
}
})();
})();
Tienes que cambiar la forma en que configuras eso:
window.onload = function(){
var animBtn = document.getElementById(''startAnim'');
animBtn.addEventListener(''click'', function() { Animation.init(); }, false);
}
En JavaScript, el hecho de que una función se defina como parte de un objeto literal realmente no significa mucho (de hecho, en realidad). La referencia a Animation.init
lo lleva a la función adecuada, pero el problema es que cuando se invoca la función (como respuesta a un "clic" real), el navegador llama a la función pero no tiene idea de que el objeto "Animación "Debería ser this
referencia. De nuevo, el hecho de que la función haya sido declarada como parte del objeto no tiene ninguna importancia aquí. Por lo tanto, si desea que this
sea algo en particular de su propia elección, entonces debe asegurarse de que esté establecido explícitamente en el código que controla. La solución anterior es sobre la forma más sencilla de hacerlo: maneja los eventos de "clic" con una función anónima que no hace otra cosa que invocar la función "init" a través de una referencia explícita a través de "Animación". Eso asegurará que se refiera al objeto "Animación" cuando se ejecute "init".
Otra alternativa sería utilizar la función ".bind ()" que admiten algunos navegadores y marcos:
window.onload = function(){
var animBtn = document.getElementById(''startAnim'');
animBtn.addEventListener(''click'', Animation.init.bind(Animation); }, false);
}
El efecto neto es casi exactamente el mismo: esa llamada a ".bind ()" devuelve una función que invoca la función en la que fue llamada (que es la función "init" en el objeto "Animación"), y lo hace con Su primer argumento como this
referencia (el objeto "contexto"). Eso es lo mismo que obtenemos del primer ejemplo, o efectivamente lo mismo de todos modos.
Una explicación de lo que está pasando. La respuesta de Pointy es buena, pero quiero explicarlo más genéricamente. Una muy buena investigación sobre this
se puede encontrar here
Un controlador de eventos es sólo una devolución de llamada. Le pasas una función y un evento para escuchar. Interamente todo lo que hará es llamar a esa función.
Animation.init es solo un captador para esa función. Piensa en esto, de esta manera:
var callback = Animation.init
animBtn.addEventListener(''click'', callback, false);
...
// internal browser event handler
handler() {
// internal handler does stuff
...
// Oh click event happened. Let''s call that callback
callback();
}
Así que todo lo que has hecho es pasado.
var callback = function(){
this.doTheMove(); // I''m calling the function here, but it gives an error.
}
Por defecto en javascript this === window
. Esto se referirá al objeto global si no está configurado a algo. El efecto neto es que se llama a window.doTheMove
. Y esa función no existe.
En este caso, dado que un controlador de eventos llama a la devolución de llamada, this
objeto apunta al objeto DOM que desencadenó el evento, por lo que su node.doTheMove
sigue sin existir.
Lo que querías hacer es envolverlo con una referencia a la animación.
var callback = function() {
Animation.init();
}
Esta es una función de ejecución y ejecuta init
en Animation
. Cuando lo ejecute en un objeto como ese, entonces internamente this === Animation
como usted esperaría.
Para resumir. El problema aquí es que Animation.init
es solo una referencia a una función. No tiene información sobre otra cosa como Pointy mencionó.