[ACCEPTED]-best approach to member variables in object-oriented javascript?-javascript
You should get over your aversion to using 11 the this
pointer to access member variables.
Assign 10 member variables in the constructor, and 9 you can access them with prototype methods:
function Cat(){
this.legs = 4;
this.temperament = 'Apathetic';
this.sound = 'Meow';
}
Cat.prototype.speak = function(){alert(this.sound)}
var cat = new Cat();
cat.speak();
Yes 8 those object attributes are public but, as 7 Guido would say, we're all adults here. Javascript 6 is, after all, a plain-text, loosely-typed, interpreted 5 language. The benefits of "private" variables 4 in this environment are shaky at best.
I 3 say just be explicit and obvious about how 2 your object should be accessed, and violators 1 will stray from that at their own risk.
The visiblity of object attributes varies 1 according to how you declare them
function Cat( name ) {
//private variable unique to each instance of Cat
var privateName = 'Cat_'+Math.floor( Math.random() * 100 );
//public variable unique to each instance of Cat
this.givenName = name;
//this method has access to private variables
this.sayPrivateName = function() {
alert( privateName );
}
}
//this variable is shared by all cats
Cat.prototype.generalName = 'tiddles';
//this method is shared by all cats and has no access to private vars
Cat.prototype.sayname = function( type ) {
alert( this[type+'Name'] || 'private!' );
}
var vic = new Cat('Victor');
var ellers = new Cat('Elmore');
vic.sayname('general'); //tiddles
vic.sayname('given'); //Victor
vic.sayname('private'); //private - no access
vic.sayPrivateName(); //cat will say its name
ellers.sayname('general'); //tiddles
ellers.sayname('given'); //Elmore
ellers.sayname('private'); //private - no access
ellers.sayPrivateName(); //cat will say its name
You should use the prototype to store methods, because 4 when you find yourself with 100 methods, they're 3 not copied around between instances rather 2 they use the same prototype. I use something 1 along these lines:
var myClass = function(){};
myClass.prototype = {
method1: function(){}
,method2: function(){}
};
A (not so) small remark on 'private' variables 16 when assigning methods to the prototype:
It's 15 true that you can't use the constructor 14 to create a closure over it's variables, but 13 you can of course surround the prototypical 12 methods with an anonymous function and get 11 private variables shared between instances 10 of the object:
function Foo() {}
(function() {
var sharedPrivateVar;
Foo.prototype.methodWithAccessToSharedPrivateVar = function() {};
})();
With some further twiddling, you 9 can implement your own protection mechanisms, eg 8 variables wich can only be read, not written 7 via:
function Foo() {
this.registerInstance({ bar : 'baz' });
this.registerInstance = undefined;
}
(function() {
var store = {}, guid = 0;
Foo.prototype.registerInstance = function(protectedProperties) {
this.__guid = ++guid;
store[this.__guid] = protectedProperties;
};
Foo.prototype.getProtectedProperty = function(name) {
return store[this.__guid][name];
};
})();
This approach won't suffer from extensive 6 function object and closure creation, but 5 increases lookup-times by a small amount.
Edit: You 4 should also provide a function
Foo.prototype.unregisterInstance = function() {
delete store[this.__guid];
};
Otherwise, this 3 is a nice way to introduce a memory leak...
Edit2: You 2 can also get around the need for a registerInstance()
function 1 with the following pattern:
Foo = (function() {
var store = {}, guid = 0;
function Foo() {
this.__guid = ++guid;
store[guid] = { bar : 'baz' };
}
Foo.prototype.getBar = function() {
var privates = store[this.__guid];
return privates.bar;
};
Foo.prototype.destroy = function() {
delete store[this.__guid];
};
return Foo;
})();
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.