Reputation: 2001
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.
Upvotes: 2
Views: 81
Reputation: 2870
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.
Upvotes: 2
Reputation: 664538
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.
Upvotes: 0
Reputation: 34895
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 );
}
Upvotes: 0