Why do we need private variables? - javascript

What are they for and how do we make it? Can you give me an example?

To avoid collisions with multiple libraries, for example.
Say they both use a variable commonly used such as data. If both libraries use private variables it's all fine:
var lib1 = (function() {
var data;
return {
get: function() { return data },
set: function(v) { data = v }
};
})();
// Supposed to do something different:
var lib2 = (function() {
var data;
return {
get: function() { return data },
set: function(v) { data = v }
};
})();
lib1.set(123);
lib2.set(456);
lib1.get(); // 123
lib2.get(); // 456
However suppose they don't use private variables but global ones like this:
var lib1 = (function() {
return {
get: function() { return data },
set: function(v) { data = v }
};
})();
// Supposed to do something different:
var lib2 = (function() {
return {
get: function() { return data },
set: function(v) { data = v }
};
})();
lib1.set(123);
lib2.set(456);
lib1.get(); // 456 - overwritten by lib2. lib1 might not work properly anymore.
lib2.get(); // 456
So lib1.get() will fetch the same data as lib2.get().
This example is too obvious of course but to stay safe it's a good practice to use private variables.

Variables are encapsulated within a class to stop their names colliding. These can be public or private. Sometimes there is a need to make sure that variables are only changed using the functions that set them. For example the parts of a date would need to be verified to stop someone setting an invalid date such aas February 45th.
var factorial = (function(){
var precog = [1,1];// ===undefined for other indices, N = undefined || N
return function(y){
return precog[y] || (precog[y]=y*arguments.callee(y-1));
};
})();
Here is a JavaScript function with a private precog. This stores previously calculated values and it is private to stop them being manipulated.

I believe there are multiple reasons for namespaces. One way I understand it is: private, protected, and public expressions help a lot in team environments so that other devs don't end up using methods you didn't intend them to. That being said, you only use private when methods or properties only need to be accessed by that same object. Use protected when you need an inheriting class to carry that same functionality and use public when an object of a different class needs to access your object.
eg:
Class Victim has
private method haveAnxiety()
public property appearsToBeRich:Boolean
Class Robber has
private method profile(obj:Victim)
private method rob(obj:Victim)
Robber->profile() will need to access Victim->appearsToBeRich. If Victim->appearsToBeRich returns true, then that Victim object will get robbed. a Robber object never needs to run Victim->haveAnxiety as the Victim will run this->haveAnxiety() as soon as that Victim object starts getting robbed.
Granted, real world examples are a LOT more complex than my example (and I hope they are much more graceful). Anyway, I hope that helps.

Related

Return structure on JS Module Pattern

Building a best practices for a manual on Module Patterns (for an internal's firm course) We come to the needs of easy discussion on the public contract and the persistence of each object. So the team is divided between two structures:
CLASSIC:
// Namespace for the library
var myFunPattern1 = {};
// Library definition
myFunPattern1 = (function () {
// Private variables / properties
var myPrivateVar = "anyValue"
// Private methods
function anyPrivateMethod(parameter) {
...
return "whatever";
}
// Public API
return {
anyPublicMethod: function (parameter) {
...
return "whatever";
}
};
})();
THE OTHER:
// Namespace for the library
var myFunPattern2 = {};
// Library definition
myFunPattern2 = (function () {
// Public API
return {
anyPublicMethod: internalNameForPublicMethod
};
// Private variables / properties
var myPrivateVar = "anyValue"
// Public methods
function internalNameForPublicMethod(parameter) {
...
return "whatever";
}
// Private methods
function anyPrivateMethod(parameter) {
...
return "whatever";
}
})();
we see the first of more "code elegant" while the second enables faster development and clear conversation between teams (once the return is defined with the documentation for parameters and so on, each developer can start working on the rest of the code
also, changes on the functionality (i.e A/B testing on function performance), on first mode need to be changed the function, on second, only the internal reference. Even, that may could be done dynamically ...
some of us think the second may raise some inconsistencies and force dependencies (public functions being declared first, or invoque before declaration), others we think we are safe ...
any other consideration??

Limiting access to JavaScript variables

I'm modifying a module for a game that we are developing and it is built with ImpactJS game engine. What we wanted to do is to make the variables private or inaccessible to other classes.
For example:
this.object.variable = 100; // Not okay.
this.object.setVariable( 100 ); // Okay.
ig.module(
'game.data.server'
).requires(
).defines(function(){
ServerData = ig.class.Extend({
_variable : -1,
get variable() {
return this._variable ;
},
setVariable: function( value ) {
this._variable = value;
}
});
});
But JavaScript setter and getter return different outputs
We can't do several revisions because this is also accessed by other games that we are developing.
Is there a better solution?
First possibility
You could try doing this but as I haven't developed anything using ImpactJS it may not work as expected as it depends what the .class.extend() function does internally.
But it's worth a try.
var ServerData = ig.class.Extend((function() {
var privateVar = -1;
return {
getVariable: function() {
return privateVar;
},
setVariable: function(value) {
privateVar = value;
}
};
})());
This code may seem a bit confusing to you, but what I've changed I've created an immediately executing function to create a function closure, which is required to create private space in which I created private to closure variable that's not visible outside.
I would suggest you to read Douglas Crockford's Javascript and learn even more stuff about the language you're using.
Second possibility
According to link in comments it seems that we can use define's closure for private members as well:
var privateVar = -1;
var ServerData = ig.class.Extend({
getVariable: function() {
return privateVar;
},
setVariable: function(value) {
privateVar = value;
}
});

JavaScript Class Best Practice?

I'm currently looking into different patterns for building classes in JavaScript. But no matther what pattern I see, there are still some things I am not really sure about.
var ItemManager = (function()
{
var p = function()
{
this.items= [];
};
p.prototype.addItem = function(item)
{
var self = this;
self.items.push(item);
};
return p;
}());
I create the simple class ItemManager, this class got the function addItem for adding any item to the collection. Now I don't really want the variable items, which represents the collection, to be public, this variable should be private, but I don't see any possible way to use a prototyped method to access private variables.
So what's the best practice in this case? Simply don't use private variables?
var ItemManager = function() {
var items = [];
return {
addItem : function(item) {
items.push(item);
},
removeItem : function() {
return items.pop();
}
}
};
var myItemManager = new ItemManager();
items variable becomes hidden after the execution of ItemManager function, but addItem and removeItem still share the access to items. See the Douglas Crockford's article on private variables in JavaScript for further investigation.
There are several ways to have private variables:
Closures, as in aga's example, which uses the Revealing Module Pattern. If you're using ES6 classes, you can hide private data in the constructor, though it looks pretty ugly to me.
[ES6] Symbols
[ES6] WeakMap
I favor Symbols, though they can still be found using reflection (i.e. not completely private). Example:
var Person = (function() {
var nameSymbol = Symbol('name');
​
function Person(name) {
this[nameSymbol] = name;
}
​
Person.prototype.getName = function() {
return this[nameSymbol];
};
​
return Person;
}());
So it's possible to have (reasonably) private variables, but unfortunately none of the solutions are as elegant as you'd like.
as GoldenerAal mentioned, they are not called classes, but functions
you have
var ItemManager = function (){
..
...
...
};
you could have:
function ItemManager(){
this.items = [];
function addItem(item){
...
};
};
you can then create an instance of ItemManager, only when you need to :
var itemManager = new ItemManager();
itemManager.addItem(<something here>);
http://javascript.crockford.com/private.html
variables inside a function only have the scope of that function, that variable is not a global variable (static variable).

Creating new JS library - Help deciding the base structure

Im creating a new library for a company. The structure I follow is
(function() {
var lib = function() {
//some private and public fn definitions
//setting publically avbl functions
return {
func1 : func1, func2: func2
};
};
return (window.lib = lib);
})();
Now how I call this is
lib.func1();
I want to be able to call my library as
lib(function | string | object).someproperty
How do I convert my code. Tried something like this
function lib() {
return new arguments.callee(arguments);
}
lib.prototype={
publicfunc: function() {
}
}
In this i'm having some problems accessing private functions since it is out of the scope for the public functions defined in the lib's prototype.
var lib = (function (param) {
var func = function () {
/// your code
return {
animate : function () {
// do the animation
return this;
}
}
return func;
})();
this can be the basic fprmat.
ok here is how i can be used.
lib(function() {...});
or
lib(selectItem).animate();
because i returned this i can run another method if there is any.
lib(selectItem).animate().animate().animate().animate() ....;
i hope you can find a use of this format, of course i made it very basic
In this i'm having some problems accessing private functions since it is out of the scope for the public functions defined in the lib's prototype.
This is because there is no such thing as private there is only local. You cannot access local variables out of scope.
The prototype cannot talk to local variables in the constructor. There are various hacks around this like keeping a public hash of instances but then you lose the "privacy"

Better way to access private members in Javascript

After reading a bit on Javascript's prototypical inheritance model, I change my style of constructing a class from
var Some_Class = function() {
this.public_method = function() {
};
(function() {
// constructor
}).call(this)
}
to
var Some_Class = function() {
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
};
Although I understand that this is a good practice, but I am not allowed to access private methods from the public method anymore
var Some_Class = function() {
var private_member = 'whatever';
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
return private_member; // not possible
};
After reading through an article here (Closure-created constructor), then I came out with this
var Some_Class = function() {
var private_member = 'whatever',
private_method = function(_some_value) {
// private method implementation
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
However, what are the drawbacks of doing this?! or is there a better way of doing this if I want to access private member in the public method?
My answer is a non-answer: there's no built-in private access in JavaScript but that's okay because YAGNI. Here's how I make private members in my code:
function Some_Class() {
this._private_member = 'whatever';
}
Some_Class.prototype._private_method = function() {
};
That's good enough. It's not really worth it to jump through hoops when the only real purpose of private is to protect yourself from... yourself.
(I say this having spent many hours myself playing around with every permutation of closures and prototyping, just as you are, and finally saying "screw it, it's not worth it".)
The use of function scope variables and closures to simulate private variables/functions is a well established idiom in the javascript community. If the variable is truly intended to be private, I see no drawback to this approach (although some claim that performant code on certain browsers/hosts has to pay attention to how many closures get created).
In your example, the private_method (and its environment) is shared across all objects - since your public_method closure is created only the first time the object is constructed (and bound to the constructor's prototype property that sets the created object's internal prototype chain) - so the private_method that is used is only the one that was created the first time.
Here is some sample code that will help illustrate what is going on:
var global = 1;
var Some_Class = function() {
var private_method = 'whatever';
var now = ++global;
print("outer now: " + now );
private_method = function(_some_value) {
// private method implementation
print("inner now: " + now);
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
new Some_Class().public_method(); // outer now: 2, inner now: 2
new Some_Class().public_method(); // outer now: 3, inner now: 2
new Some_Class().public_method(); // outer now: 4, inner now: 2
Are you sure that is what you want?
If your private_method does not need to refer to the enclosing object's state, then I see little benefit in doing things the way you are doing.
What I usually do (if i have to use 'new' to create my object) is the following:
function MyClass() {
var private_var = 1;
function private_func()
{
}
this.public_func = function()
{
// do something
private_func();
}
this.public_var = 10;
}
var myObj = new MyClass();
The downside to this approach is that each time you construct the object via 'new' you re-create all the closures. But unless my profiler tells me that this design choice needs to be optimized, i prefer its simplicity and clarity.
Also I don't see the benefit in your code of doing the following either:
(function() { }).call(this); // call the constructor
Why are you creating a separate scope in your constructor?
If you have not done so already have a look at this JavaScript Module Pattern, which allows you to access private methods and variables from within the public functions, etc.
Echoing John Kugelman: It's impossible to create private members in javascript. Live with it. Even if you create a enclosure like this:
function SomeClass() {
var _private = 0;
this.public_acessor = function() {return _private};
}
Any user can still write:
SomeClass._not_private_anymore = 1;
SomeClass.public_acessor = function () {return this._not_private_anymore};
In the end, you can't trust any public member to be the same you declared. If someone is up to break your code, he will! Another user won't break your code only because it's useful.
Works with prototype, not just singleton. Problem is, when it's time to subclass, my subclass has no access to the privates

Categories

Resources