Javascript "private" vs. instance properties

I do Javascript R & D, and although I read Javascript: the ultimate guide and Javascript object-oriented programming , I still have a minor letting go of my OOP class and object-based lexical OOP.

I like the modules. Namespaces, subclasses, and interfaces. w00t. Here is what I play 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") } } }) 

I am trying to find the best way to modular code (and understand prototyping) and share everything. The Globe notification is a feature that needs to be created using new , Umbrella is single-point and has already been announced, Igloo uses what I thought at work today and seems to work just as well as it hopes, and House is still one Iglooesque function for testing.

The result of this:

 Globe unavailable Igloo My House 

So far so good. The Globe prototype must be declared outside the Classes object for syntax reasons, Umbrella cannot accept because of its existing one (or an instance created or ... dunno the "correct" term for this), and Igloo has some closure that declares this for you .

BUT...

If I had 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 in _name (the "private" property), it does not work and instead outputs:

 My House unavailable My House My House 

Will anyone be kind enough to explain this? Obviously, _name overwritten at each iteration and does not read the property of the object to which it is bound.

It all seems too complicated if you need this and a kind of weird IMO.

Thanks:)

+4
source share
2 answers

You are declaring a global variable. It is available anywhere in your code after announcing it. Wherever you request _name (more closely window._name ), you will get global every time. In your case, _name was replaced in each function. The final feature is House, and My House has been installed.

The declaration of "private" (local) variables must be with a var statement.

Check this:

 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 

Must 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 
+5
source

If you delete the keyword "this", then _name is in the "Globe" area.

Looking at your code.

 var globe, umb, igloo, house; globe = new Classes.Globe(); umb = Classes.Umbrella; igloo = new Classes.Igloo("Ice"); house = new Classes.House(); 

Finally, the house will override the value of "_name" in the globe area with the name "My Home".

+1
source

Source: https://habr.com/ru/post/1390617/


All Articles