SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    38911 Basic Bytes Free johnuk's Avatar
    Join Date
    Jul 2008
    Location
    Somerset, England
    Posts
    458
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    'This' is undefined when calling from instance method

    Hi guys,

    I am experimenting with OO JavaScript in a test script with the intent of building a soundboard application later down the line.

    I learn't to program in Java so I am o fay with the concepts of OO programming, and after reviewing the JS Object Syntax I feel confident with using Objects in JavaScript.

    Up until now I have had no problem referencing instance variables from within methods using the 'this' keyword.

    For some reason on of one my test Objects, a 'Key Strok listener', I cannot seem to access instance variables from inside the Object - but I can access them outside the object!

    This seems totally nuts to me as Ive not had a problem with such a simple task before, here is a code snippit;

    Code:
    //Stroker Constructor
    function Stroker()
    {
    	//Assign Instance of PlaySound to this Object
    	this.objPlaySounds = "Tune"; //I replaced the actual object here with a string for testing
    	//Invoke this Object's keyStroker Method
    	Stroker.prototype.keyStroker();
    }
    
    Stroker.prototype.getObjPlaySounds = function()
    {
    	return this.objPlaySounds;
    }
    
    //Stroker Methods
    Stroker.prototype.keyStroker = function()
    {
        document["onkeydown"] = function(event)
    	{  
            var keycode;
            //IE hack
            if(typeof event == "undefined") 
    		{
                event = window.event; 
            }
            //IE different event object
            if(typeof event.which == "undefined") 
    		{
                keycode = event.keyCode; 
            }
            else
    		{
                keycode = event.which;
            }     
            Stroker.prototype.processKeyStroke(keycode); 
            alert(Stroker.prototype.getObjPlaySounds()); //Returns Undefined
            alert(this.objPlaySounds);//Returns Undefined
        };
    };
    
    Stroker.prototype.processKeyStroke = function(strKeyCode)
    {
    	if(strKeyCode == 75)
    	{
    		alert("k");
    	}
    	if(strKeyCode == 74)
    	{
    		alert("J");
    	}
    }
    
    /*--------------------------------------------------------------------------------------------*\
    	End KeyStroker Test Object
    \*--------------------------------------------------------------------------------------------*/
    
    var objStroker = new Stroker();
    alert(objStroker.objPlaySounds); //returns "Tune"
    alert(objStroker.objPlaySounds);  //returns "Tune"
    alert(objStroker.getObjPlaySounds());  //returns "Tune"
    Does anyone have any idea why this is happening?


    Many thanks!

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,676
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by johnuk View Post
    Does anyone have any idea why this is happening?
    When the event is triggered, the this keyword refers to the element to which the event is assigned. That being the document in your example.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    38911 Basic Bytes Free johnuk's Avatar
    Join Date
    Jul 2008
    Location
    Somerset, England
    Posts
    458
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Paul, thanks for your reply. I'm with you - I figured it had to be something to do with events since all my other classes allow me to access their own instance variables.

    My question is then, how should I go about accessing this.objPlaySounds without referring to the document?


    kind regards and thanks

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,676
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by johnuk View Post
    My question is then, how should I go about accessing this.objPlaySounds without referring to the document?
    You can either access it globally, or you can place a reference to it on an object that is easily accessible. For example:

    Code javascript:
    document.relatedObject = Stroker;
    document.onkeydown = function (event) {
        that = document.relatedObject ;
        document.relatedObject = undefined;
     
        // use that in here instead of this
        ...
    };
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,244
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Also...

    Quote Originally Posted by johnuk View Post
    Code:
    //Stroker Constructor
    function Stroker()
    {
    	//Assign Instance of PlaySound to this Object
    	this.objPlaySounds = "Tune"; //I replaced the actual object here with a string for testing
    	//Invoke this Object's keyStroker Method
    	Stroker.prototype.keyStroker();
    }
    The highlighted line needs to be written as...

    this.keyStroker();

    Otherwise the method call loses the "this" value. You'll need to make the same kind of fix in a few other places in your code as well.
    "First make it work. Then make it better."

  6. #6
    38911 Basic Bytes Free johnuk's Avatar
    Join Date
    Jul 2008
    Location
    Somerset, England
    Posts
    458
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    You can either access it globally, or you can place a reference to it on an object that is easily accessible. For example:

    Code javascript:
    document.relatedObject = Stroker;
    document.onkeydown = function (event) {
        that = document.relatedObject ;
        document.relatedObject = undefined;
     
        // use that in here instead of this
        ...
    };
    Thanks Paul, will do!
    Last edited by paul_wilkins; Sep 14, 2012 at 15:23. Reason: code correction in quoted section

  7. #7
    38911 Basic Bytes Free johnuk's Avatar
    Join Date
    Jul 2008
    Location
    Somerset, England
    Posts
    458
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks also Jeff - will do


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •