4

I am trying to understand objects in javascript. Here is the code:

var fn={};
var canvas;
var ctx;
fn.game=function(width,height,inSide,name){
    this.canvas2=document.getElementById(inSide).innerHTML = "<canvas id="+name+" style='width:"+width+";height:"+height+";'>Your browser does not support the Canvas Element.</canvas>";
    this.canvas=document.getElementById(name);
    this.ctx=this.canvas.getContext("2d");
    document.getElementById(inSide).style.width=width;
    document.getElementById(inSide).style.height=height;
    canvas=document.getElementById(name);
    ctx=this.canvas.getContext("2d");
    this.width=width;
    this.height=height;
    canvas.width=width;
    canvas.height=height;
    this.add={

    };
    this.add.state=function(name){
        this[name]=3;
    };
};


var game=new fn.game(640,480,"game","canvas");

game.addState("play");

when I am referencing this["name"] I am trying to refer this to fn.game, but that dous not work because this references the most local object. Any ideas on how to do this?

  • 2
    What is `game.addState`? I don't see that anywhere here. You have `game.add.state`, is that the function you are trying to call? – Rocket Hazmat Dec 22 '14 at 23:32
  • Hi @andrew, please take a look at answers here: http://stackoverflow.com/questions/8670877/this-value-in-javascript-anonymous-function . These address the same issue that in the anonymous function, this is bound to the global object – Dmitry Evseev Dec 22 '14 at 23:32
  • It looks to me that Augmentation could be useful in this scenario. – Andrew Ice Dec 22 '14 at 23:40

4 Answers4

5

As you said, it references the most local object, to do what you explained :

...
fn.game=function(width,height,inSide,name){
    var that = this;//expose this of fn.game to this scope
    ...
    this.add={

    };
    this.add.state=function(name){
        that[name]=3;//access this of fn.game
    };
};
topheman
  • 6,374
  • 4
  • 20
  • 32
3

There are a couple of ways to do this, and it depends on the way you're doing it, although I think the biggest issue you've got is that your object has no declared function of addState() so when I tried to run your code it just gave me an error. In the code below I changed it, and it should work how you want it to currently.

var fn = {};
var canvas;
var ctx;
fn.game = function(width, height, inSide, name) {
  this.canvas2 = document.getElementById(inSide).innerHTML = "<canvas id=" + name + " style='width:" + width + ";height:" + height + ";'>Your browser does not support the Canvas Element.</canvas>";
  this.canvas = document.getElementById(name);
  this.ctx = this.canvas.getContext("2d");
  document.getElementById(inSide).style.width = width;
  document.getElementById(inSide).style.height = height;
  canvas = document.getElementById(name);
  ctx = this.canvas.getContext("2d");
  this.width = width;
  this.height = height;
  canvas.width = width;
  canvas.height = height;
  this.add = {

  };
  this.addState = function(name) {
    this[name] = 3;
    console.log(this);
  };
};


var game = new fn.game(640, 480, "game", "canvas");

game.addState("play");
<div id="game"></div>

HOWEVER

If you'd like to have that same syntax as before, of game.add.state(), then something like either of the below examples should work:

Example 1

Link to Function.Prototype.Bind

//Rest of code
this.add={};
this.add.state = function(name){
   this[name]=3;
}.bind(this)
//Rest of code

Example 2

Javascript Variables and Scope

//Rest of code
this.add={};
var self = this;
this.add.state = function(name){
    self[name]=3;
}
//Rest of Code
Jhecht
  • 4,040
  • 1
  • 26
  • 39
2

every time you are inside a function() the meaning of this changes to the current function

all you need to do is save the reference to the object you want to access

fn.game=function(width,height,inSide,name){
    var self = this;
    this.add.state=function(name){
        self[name]=3;
    };
};
bto.rdz
  • 6,322
  • 4
  • 32
  • 49
1

In order for this to mean mean fn.game, you would need to do something more like:

var doc = document, bod = doc.body;
function E(e){
  return doc.getElementById(e);
}
function C(t){
  return doc.createElement(t);
}
function FnGameAdd(){
  this.state = function(popertyName){
    this[propertyName] = 3;
  }
}
function FnGame(canvasId, width, height, inside){
  // style with CSS
  inside.innerHTML = "<canvas id='"+canvasId+"'>Your browser does not support the Canvas Element.</canvas>";
  var cv = this.canvas = E(canvasId);
  cv.height = height; cv.width = width; this.ctx = cv.getContext('2d');
  this.add = new FnGameAdd;
};
}
var fn = {};
fn.game = function(canvasId, width, height, inside){
  // this.prop = 'belongs to fn';
  return new FnGame(canvasId, width, height, inside);
}
new fn.game('canvas', 640, 480, E('game'));

/* keep this for fun of creating new Object literals, not needed here
Object.create = Object.create || function(obj){
  function F(){}; F.prototype = obj;
  return new F;
}
var newObj = Object.create(fn);*/
StackSlave
  • 10,198
  • 2
  • 15
  • 30