2

I'm trying to build a simple application where I'll be creating multiple instances of a Box object which will control and manipulate its own data. However, I'm having trouble figuring out how to create global variables for use within each individual object and it's associated prototypes...

For example, I tried to make a reference to itself...

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    var boxName = boxData.name;

    var canvas = $( '#rm-' + boxData.id ).find( 'canvas' )[0];
    $( canvas ).on( 'mousedown', this.onMouseDownHandler );
}

Box.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( this.boxName );
}

Keep in mind that it can't act as a singleton as I'll have multiple instances of it at any one point in time.

Edit:

I'm adding the event listener in the constructor with, updated the above code.

2
  • How are you executing your Box.onMouseClickHandler ? I think you aren't binding it correct, but need an example to find where you got the error. Give a usage example please. Commented Jan 9, 2013 at 7:31
  • Updated with the event listener Commented Jan 9, 2013 at 7:41

3 Answers 3

2

For your canvas work with Box instance as it context, you need to bind it.

You can try something like this:

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    var boxName = boxData.name;

    // public property boxName
    this.boxName = boxName;

    var $canvas = $( '#rm-' + boxData.id ).find( 'canvas' );
    $canvas.on( 'mousedown', this.onMouseDownHandler.bind(this) );
    // ----------------------------------------------^
    // this bind will prevent the event use canvas element as context
}

function Room() {
    // some stuff
}

Room.prototype = new Box({name: 'this will always be my rooms box'});

Room.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( this.boxName );
}

Now you are able to try this:

var foo = new Room();
foo.onMouseClickHandler();

And your console will log this will always be my rooms box.

You keep in mind that Room extends a instance of Box, so if you do:

foo.boxName = 'my name is what?!';

// you changed the this so the prototype will get the new value:
foo.onMouseClickHandler(); // 'my name is what?!'

EDIT (after question upgrade)

Simply use this.boxName instead var boxName:

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // public property boxName
    this.boxName = boxName;
}

And if you want to add a EventHandler for other object but keep your Box context you need to do this:

var foo = newBox({boxName: 'foo'});
var bar = document.queryElementById('bar');

bar.addEventHandler('click', foo.onMouseClickHandler.bind(foo));

Now if you click in bar element, the onMouseClickHandler from foo, will keep it context. The click event will be passed throw the argument.

Sign up to request clarification or add additional context in comments.

5 Comments

Sorry, I updated the initial question. Both the prototype and the constructor were supposed to say Box...
Problem is, 'this' when used in an event handler does not refer to the Box objects instance.
@user1960364 I'm imagine how you are triggering the method onMouseCLickHandler in my last answer update, because you haven't been explicit in your question, but I have good feelings that will help you.
I've updated the question again, including my event listener.
@user1960364 and I've updated the answer with what you need, close look :)
0

You create global variables as properties of the global object (window). You can have something of the sort: window['box_instance_key']['name'] to store every instance's name.

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // I need to access this later...
    window.boxName = boxData.name;
    // or something like window[boxData.id]['boxName'] = boxData.name;
}

Room.prototype.onMouseClickHandler = function( event ) {
    // 'boxName' is undefined as 'this' references 'event.target'
    console.log( window.boxName );
}

3 Comments

Wouldn't window.boxName interfere with other Box instances? And in your comment, you say to use box_instance_key - but how do I get the instance key from within the instance?
@user1960364 Yes that is why I added the comment up top saying you can use some kind of instance ID to separate them. I updated the code with a comment.
Sorry, the prototype should be Box.prototype... Updated the question. Therefore, I'm still unsure how I can get boxData.id from within the prototype.
0

You've actually got two problems.

variable scopes

Variables in JS always have function scope. A local variable in the constructor function will stay local to the constructor, and cannot be used outside.

create global variables for use within each individual object

it can't act as a singleton

Global, static variables seem to be the opposite of what you want. I guess you meant public object property instead of global variable. So use one:

function Box( boxData ) {
    // References the Box instance as I want.
    console.log( this );

    // create a property to be accessed later...
    this.boxName = boxData.name;
}

'boxName' is undefined as 'this' references 'event.target'

Yes, the context of the function depends (only) on its invocation. You will need to use

 var that = this;
 ….addEventLister(…, function(event) {
      that.onMouseClick(); // "that" references the instance
 });

for registering the event.

1 Comment

you can bind the context too, so the invocation won't touch it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.