recorrer objetos objeto new metodos lista eliminar elementos elemento clases array agregar javascript object-literal

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ó.