I am having a problem with closures I think. I am really new to doing OOP JavaScript ONLY (I started this week...) but I have used JavaScript for little DOM manipulation stuff here or there and JQuery magic quite a few times. I am looking for a solution to my problem that does not involve changing my criteria because I want to try and finally learn proper JavaScript. My criteria is that I want the solution to be able to maintain my encapsulation and Java style publicly accessed private variables. My criteria also needs the solution to be able to teach me a bit about closures without repeating the examples at [thisPage]:How do JavaScript closures work? .
I have scoured the internet for a solution to my problem and the videos I have been finding, the books I red in school, the net pages I have red and the S.O. posts I have gone through have not yet shown me a good answer to why this is happening. That or I just really cannot grasp closures or whatever this problem is...
I have a class like this:
var Animal = {
$name: "Blank",
$age: -1,
setName: function(n) {this.name=n;},
setAge: function(a) {this.age=a;}
};
To which I then afterwards call...
Moose.prototype = Object.create(Animal);
Moose.prototype.constructor = Moose;
function Moose(newName, newAge) {
this.setName(newName);
this.setAge(newAge);
}
The this
in this.setName()
does what I want and finds Animal and adds a name to my moose without causing its Moose brethren to be also called "moosey moose mcDonkeybutt" or something....
I can successfully then, in console, create two 'Meese' or Mooses if you will and each has their own separated values. Like...
m1 = new Moose("MooseyMoose", 420);
m2 - new Moose("MooseMcTingles", 69);
And m1 wouldn't have the same values as m2 when inspected. Which is what I would expect from the other languages I have used over the years.... However this is where I get confused or at least glaring at my computer like, whoa, "what the douce?"
I want to add some kind of ability to gauge how each animal is moving over time. So I thought, hey, why not take this time to use the awesome power and simplicity of object literals to store this inside my class.... like so....
var Animal = {
$name: "Blank",
$age: -1,
$position: {x:-1,y:-1},
setName: function(n) {this.name=n;},
setAge: function(a) {this.age=a;},
getName: function() { return this.name; }
};
So I add in my accessor with a bit of extra load...
var Animal = {
$name: "Blank",
$age: -1,
position: {x:-1,y:-1}, //I have tried $ and without
setName: function(n) {this.name=n;},
setAge: function(a) {this.age=a;},
getName: function() { return this.name; },
//New Accessor
setPosition: function(newX, newY) {
this.position.x = newX;
this.position.y = newY;
}
};
As I am sure the experienced programmers are reading at this point and saying... what an idiot. Problem is I have not read, searched or found the answer to have my AHH HA!! moment to this next part. If you already guessed what I am gonna have wrong you prolly should answer. Why on earth is this causing both m1
and m2
to have the same shared values on position now? Its not because its publicly declared I have tried with a private scope as well and it just makes it even harder for the this
to find the correct prototype.
I have tried so SO many version of code on this block to try and figure out why I can't seem to store my position as a simple little object literal with easy access... I need all instances of Moose() to not be able to change each others position by using the setPosition()
function above....
Also. I have tried converting it all to a function
object rather than a var Object and I have also tried removing many combo's of this
's that I knew weren't hitting the scope I need, however no luck yet. I have also tried removing the use of the .create()
method and switched to the new
keyword and also no luck.
EDIT: to the ppl replying.... like I said I have tried it all including adding getter setter methods to the position variable. It doesnt help at all it still shares the value....