Reputation: 921
Variable scope in JS is confusing the hell out of me. In the following code, if I use the setClient
public method to set a clientID
I can then access the value from inside the track method using the getClient
method. I cannot, however, access the value of the private member 'version' this way (or any other private member). I had assumed that var _this = this
would create a closure of some sort allowing access to the scope of the Container function.
And now I'm confused. I realise this is probably really simple though, so I thought I'd ask here. Where on earth have a grasped the wrong end of the stick?
function Container()
{
// private members
var version = '0.1';
var CID = false;
var _this = this;
// public members
this.getVersion = function() { return _this.version; }
this.getClient = function() { return _this.CID; }
this.setClient = function(CID) { _this.CID = CID; }
// private methods
this.getQS = function() { return _this.version; }
// public methods
this.track = function()
{
if (_this.CID)
{
var date = new Date();
data =
{
cid: _this.getClient(),
sw: screen.width ? screen.width : false,
sh: screen.height ? screen.height : false,
d: date.getTime()
}
qs = '';
for (p in data) { qs += p+'~'+data[p]+'-'; }
var elHd = document.getElementsByTagName("head")[0];
var elScr = document.createElement('script');
elScr.type = 'text/javascript';
elScr.src = 'http://example.org/'+qs+
'version-'+_this.getVersion();
elHd.appendChild(elScr);
}
else
{
alert('no client ID');
}
}
}
Upvotes: 2
Views: 714
Reputation: 2107
The simple answer is to use
this.getVersion = function() { return version; }
Because the JavaScript functions are closures the reference to version, a local variable, in the function above can be accessed even after the function returns. Trying to access _this.version
is an attempt to read the version member of the _this
object. Since you never assigned _this
a version member, it will return a value of undefined
.
In JavaScript, you'll only be able to access members that are either explicitly added to the object you're working with, or added to that object's prototype, or the prototype's prototype, etc.
More info on using private members with JavaScript can be found in a great article by Douglas Crockford: Private Members in JavaScript
Upvotes: 0
Reputation: 32520
The variable version is not a member field of the Container class. It is a local var that only exists for the duration of the Container constructor. You need to create it thus (as you are with the methods):
this.version = "0.1";
You should do the same for the CID field. Better yet, add them to the prototype object of your class.
Upvotes: 0
Reputation: 4073
Cleand up your Container constructor a bit. The version and CID variables are private and within the Container constructor scope, so you do not need the this scope reference, and it would not work at all. this. reference would be needed for public accessible properties and methods, and extremely useful when you define the prototype outside of the constructor function, as shown in the second code block.
function Container() {
var version = "0.1", CID = false;
this.getVersion = function() { return version };
this.getClient = function() { return CID };
this.setClient = function(value) { CID = value };
this.track = function() {
if (CID) {
var qs = "", data = {
cid: this.getClient(),
sw: screen.width ? screen.width: false,
sh: screen.height ? screen.height: false,
d: (new Date).getTime()
};
for (var p in data) qs += p +"~"+ data[p] +"-";
var js = document.createElement("script");
js.type = "text/javascript";
js.src = "http://example.org/"+ qs +"version-"+ this.getVersion();
document.getElementsByTagName("head")[0].appendChild(js);
} else {
alert("No Client ID");
}
};
};
this. reference becomes crucial when you are adding/overriding the prototype after the constructor.
function Container2() { }
Container2.prototype = {
CID: null,
version: "0.1",
track: function() {
alert(this.version);
}
}
Upvotes: 1
Reputation: 21950
I'm not sure I'm understanding where you are confused (or why you are doing things the way you are, so I may be meta-confused). What happens if you just do:
this.getVersion = function() { return version; }
Upvotes: 0