![](/style/images/good.png)
![](/style/images/bad.png)
Javascript & ldquo; Private & rdquo; Vs properties of the instance
source link: https://www.codesd.com/item/javascript-private-vs-properties-of-the-instance.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Javascript & ldquo; Private & rdquo; Vs properties of the instance
I'm doing some Javascript R&D and, while I've read Javascript: The Definitive Guide and Javascript Object Oriented Programming, I'm still having minor issues getting my head out of class based OOP and into lexical, object based OOP.
I love modules. Namespaces, subclasses and interfaces. w00t. Here's what I'm playing with:
var Classes = {
_proto : {
whatAreYou : function(){
return this.name;
}
},
Globe : function(){
this.name = "Globe"
},
Umbrella : new function(){
this.name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
this.name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
this.name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
Im trying to find the best way to modularize my code (and understand prototyping) and separate everything out. Notice Globe
is a function that needs to be instantiated with new
, Umbrella
is a singleton and already declared, Igloo
uses something I thought about at work today, and seems to be working as well as I'd hoped, and House
is another Iglooesque function for testing.
The output of this is:
Globe
unavailable
Igloo
My House
So far so good. The Globe prototype has to be declared outside the Classes object for syntax reasons, Umbrella can't accept due to it already existing (or instantiated or... dunno the "right" term for this one), and Igloo has some closure that declares it for you.
HOWEVER...
If I were to change it to:
var Classes = {
_proto : {
whatAreYou : function(){
return _name;
}
},
Globe : function(){
_name = "Globe"
},
Umbrella : new function(){
_name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
_name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
_name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
and make this.name
into _name
(the "private" property), it doesn't work, and instead outputs:
My House
unavailable
My House
My House
Would someone be kind enough to explain this one? Obviously _name
is being overwritted upon each iteration and not reading the object's property of which it's attached.
This all seems a little too verbose needing this
and kinda weird IMO.
Thanks :)
You declare a global variable. It is available from anywhere in your code after declaration of this. Wherever you request to _name
(more closely window._name
) you will receive every time a global. In your case was replaced _name in each function. Last function is House and there has been set to "My House"
Declaration of "private" (local) variables must be with var
statement.
Check this out:
var foo = function( a ) {
_bar = a;
this.showBar = function() {
console.log( _bar );
}
};
var a = new foo(4); // _bar ( ie window._bar) is set to 4
a.showBar(); //4
var b = new foo(1); // _bar is set to 1
a.showBar(); //1
b.showBar(); //1
_bar = 5; // window._bar = 5;
a.showBar();// 5
Should be:
var foo = function( a ) {
var _bar = a;
// _bar is now visibled only from both that function
// and functions that will create or delegate from this function,
this.showBar = function() {
console.log( _bar );
};
this.setBar = function( val ) {
_bar = val;
};
this.delegateShowBar = function() {
return function( ) {
console.log( _bar );
}
}
};
foo.prototype.whatever = function( ){
//Remember - here don't have access to _bar
};
var a = new foo(4);
a.showBar(); //4
_bar // ReferenceError: _bar is not defined :)
var b = new foo(1);
a.showBar(); //4
b.showBar(); //1
delegatedShowBar = a.delegateShowBar();
a.setBar(6);
a.showBar();//6
delegatedShowBar(); // 6
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK