prototype: deep scope of "this" to access instance's scope
How can the the top-most scope can be cached in order to be used deeper in the prototype later, like so:
var Game = function(id){
this.id = id;
};
Game.prototype = {
board : {
init: function(){
// obviously "this" isn't the instance itself, but will be "board"
console.log(this.id);
}
}
}
var game = new Game('123');
game.board.init(); // should output "123"
update:
Well now that I think about it, I can use apply
/call
and pass the context...
game.board.init.apply(game);
As you only have one instance of the board
object, there is no way for it to know what you used to access it. Using game.board
or Game.prototype.board
to access the object gives exactly the same result.
If you don't want to create one board
object for each Game
instance, you have to tell the board
object which Game
object it should consider itself to belong to for each call:
game.board.doSomething(game);
or:
Game.prototype.board.doSomething(game);
Edit:
To create one board for each Game
instance, make a constructor for Board
, and make the board object aware of the Game
instance that it belongs to:
function Game(id) {
this.id = id;
this.board = new Board(this);
}
Game.prototype = {
};
function Board(game) {
this.game = game;
}
Board.prototype = {
init: function(){
console.log(this.game.id);
}
};
var game = new Game('123');
game.board.init(); // outputs "123"
There's no such thing as 'deeper in the prototype'. "this" will always be the object that you're calling it on, unless that's changed through being a callback or various ways to rebind. You'll have less sanity loss if you split up your concepts and link them together:
Board = function (game) {
this.game = game;
}
Board.prototype.init = function () {
console.log(this.game.id);
}
Game = function () {
this.id = 123;
this.board = new Board(game);
}
Game.prototype = {};
Alternatively, if you're hellbent on making it all use the same base, you can do some crazy hack like..
Game = function () {
this.id = 123;
var self = this;
for(var p in this.board) {
var property = this.board[p];
if(typeof property == 'function') {
this.board[p] = function (method) {
return function () {
method.apply(self, arguments);
}
}(property)
}
}
}
This is a total hack, and it'll make your coworkers hate you. (If you're using the underscore library, there's a bindAll function that helps with this stuff)