Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Javascript and Scope

Name: Anonymous 2010-06-10 3:17

How do I call charizard from deep within squirtle?


var pokedexObject = {
    charizard: function() {
        console.log("I am charizard.");
    },
    squirtle: function() {
       // extenral API pseudocode incoming.
1
       $("<elem>").each(function() {
           // dom create element
           var pokePic = $("<img src=\"squirtle.png\">");
           // dom attach
           $(this).append(pokePic);
           // dom event listener
           pokePic.click(function() {
               // charizard! i choose you!
               // ...but how?
           });
       });
    }
};


______________
1. This example uses external DOM API pseudocode. The reason is that in APIs like these, nested closures are common -- perfect for illustrating the problem. I have also included comments to indicate the general DOM tasks these pseudo-calls intend to describe.

Name: Anonymous 2010-06-10 4:22

Read SICP

Name: Anonymous 2010-06-10 5:07

pokedexObject.squirtle = function

Name: Anonymous 2010-06-10 5:26

>>1
IIRC, In Javascript an "object" is basically a hash table, and doesn't have an "object-level scope", therefore you can't refer to charizard directly if you use the literal syntax. You can get this to work if you use a different method for object creation,
function pokedexObject() {
  this.charizard = function() {
    console.log("I am charizard.");
  };
  this.squirtle = function() {
    // extenral API pseudocode incoming.1
    $("<elem>").each(function() {
      // dom create element
      var pokePic = $("<img src=\"squirtle.png\">");
      // dom attach
      $(this).append(pokePic);
      // dom event listener
      pokePic.click(function() {
      // charizard! i choose you!
      // ...but how?
      });
    });
  };
}

then
var x = new pokedexObject();
x.charizard();
x.squirtle();

Name: Anonymous 2010-06-10 5:51

>>4
That doesn't really solve the problem. Not only does >>1 need to make a method call from within another method, he needs to do it within a closure which is itself within a closure. I'm assuming it's written that way because the innermost closure is being passed as a callback for a mouse click event.

This is what I do, but I'm not sure what the "best practice" is.

var  pokedexObject = {
    charizard: function() {
        console.log("I am charizard.");
    },
    squirtle: function() {
        // wrap the current "this" context into a local variable for the following closures
        var self = this;
        // extenral API pseudocode incoming.1
        $("<elem>").each(function() {
            // dom create element
            var pokePic = $("<img src=\"squirtle.png\">");
            // dom attach
            $(this).append(pokePic);
            // dom event listener
            pokePic.click(function() {
                self.charizard();
            });
        });
    }
};

Name: Anonymous 2010-06-10 6:23

>>1
var pokedexObject = {
    charizard: function() {
        console.log("I am charizard.");
    },
    squirtle: function() {
       // extenral API pseudocode incoming.1
       $("<elem>").each(function() {
           // dom create element
           var pokePic = $("<img src=\"squirtle.png\">");
           // dom attach
           $(this).append(pokePic);
           // dom event listener
           pokePic.click(function() {
               // charizard! i choose you!
               poxedexObject.charizard();
           });
       });
    }
};

Name: Anonymous 2010-06-11 12:28

People who don't understand prototypes are forced to reinvent them, poorly.

Name: Anonymous 2010-06-11 13:00

>>5
var self = this is common practice

Name: Anonymous 2010-06-11 13:09

Generally, I do what
>>5
suggests. Sometimes if I'm using MooTools I use the .bind method on callback functions. So a MooTools-ified example would look something like

var Pokedex = new Class({
    initialize:function(elements){
        this.elements = elements;
    },
    charizard: function(){
        console.log("I am charizard.");
    },
    squirtle: function(){
        this.elements.each(function(e){
            var pokePic = new Element('img', {
                'src':'squirtle.png',
                'events':{
                    'click':function(e){
                        this.charizard();
                    }.bind(this)
                }
            }).inject(e);
        }.bind(this))
    }
});


I'm not sure I'd do that in this case, but being an example I'm sure that's beside the point.

Name: Anonymous 2010-11-25 11:12

Name: Anonymous 2011-02-03 7:13


Don't change these.
Name: Email:
Entire Thread Thread List