What is mean 'private variable' in javascript?
There isn`t 'private variable' declare in javascript.
so we usually have used '_' or closure.
In this Point, I was curious 'closure'.
I got example from another site.
function createAnimal(name, job) {
// "Private" variables here
let _name = name;
let _job = job;
// Public variables here
return {
// Getter Methods
getName() {
return _name;
},
getJob() {
return _job;
},
// Setter Methods
setName(newName) {
_name = newName;
},
setJob(newJob) {
_job = newJob;
}
};
}
Above example
we can change _name 'private variable' of setName.
Reault
'private variable' mean that we can`t access variable? or constant?
I hope, this may help you:
Private members are made by the constructor. Ordinary vars and
parameters of the constructor become the private members.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
This constructor makes three private instance variables: param,
secret, and that. They are attached to the object, but they are not
accessible to the outside, nor are they accessible to the object's own
public methods. They are accessible to private methods. Private
methods are inner functions of the constructor.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
The private method dec examines the secret instance variable. If it is
greater than zero, it decrements secret and returns true. Otherwise it
returns false. It can be used to make this object limited to three
uses.
By convention, we make a private that variable. This is used to make
the object available to the private methods. This is a workaround for
an error in the ECMAScript Language Specification which causes this to
be set incorrectly for inner functions.
Private methods cannot be called by public methods. To make private
methods useful, we need to introduce a privileged method.
Reference: Read more
Private variables are hidden, and therefore can't be accessed directly. For instance, you would not be able to call animal._name = "Rover".
Instead, you're expected to call a function that encapsulates the variable. In your example, you would instead call animal.setName("Rover"). So, these variables aren't necessarily constant, but they can only be changed by calling special methods that change them internally.
Programmers like private variables sometimes, because there are situations where manipulating a variable directly could cause issues.
For instance:
function createLogger() {
let _numMessagesLogged = 0;
return {
logMessage(message) {
console.log(message);
_numMessagesLogged += 1;
},
getNumMessagesLogged() {
return _numMessagesLogged;
},
};
}
In this example, we increment a counter (_numMessagesLogged) every time a message is logged. If the counter were public, someone could set logger._numMessagesLogged = -12345, which doesn't make any sense. Instead, we want the variable to be private, so that we know for sure that the number of messages logged increases only when we log something-- that is, it increases only when we call logMessage().
Closures are just one way of implementing private members via JavaScript. There are other ways to do this as well, but the method isn't as important as the underlying concept.
You may be interested in reading more about encapsulation.
Related
In Douglas Crockford's article, Private Members in Javascript, he uses the variable "that" to refer to "this" for use in the privileged method of the class. I have been using "this.publicMember" in my code and it seems to work right. I would think the only time you would really need to use "that" would be if you are calling the function where the "this" would obviously be different, i.e. calling it from setTimeout. When should I use / not use "that" ?
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
return dec() ? that.member : null;
};
}
Versus:
this.service = function () {
return dec() ? this.member : null;
};
He writes in his article:
By convention, we make a private that variable. This is used to make the object available to the private methods.
Then he just uses that everywhere, to avoid issues with unbound functions (like the setTimeout you mentioned) and also to be easily able to switch a "method" between private and privileged. Since the method is already instance-specific anyway (not inherited from the prototype or so), it really doesn't hurt to make it bound and access one more closure variable.
In JS, there are many scenarios in which the value of this won't be the same value of this in an outer block: https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work
If you happen to need to use the outer block value of this, then you will use that.
I am trying to make sense and understand when to use private and when to use privileged methods in JavaScript. According to this post: Private Members in JavaScript, private members of an object can be accessed and modified both by private methods and privileged methods. When writing getter methods (for the private members), would you use a private or privileged method? Why? For accessors (methods that modify private members) would you use private or privileged methods? Why? What is the standard technique used in this cases?
And lastly, what is the difference in using a private vs privileged method to access a private variable (apart from the fact that the private method cannot be called from outside).
function ClassB(given)
{
var myVar = given;
function _get ()
{
return myVar;
};
this.get = function ()
{
myVar = myVar + 3;
return myVar;
};
}
When you are designing your objects you need to make a decision to start. Do you care about exposing the internals of the object to the outside world?
If you don't care, then you should really be adding all of your methods to the prototype of the object, and all your instance variable to this in your constructor function. This approach may not be desirable in some situations. This is where the privileged methods come in, as well as the usage of closures to mimic private methods.
When you create a privileged method, it has access to private and public members of the object as you've noted. The big difference between creating a privileged method and a public method on the prototype is that the privileged method is created with every instance of the object, whereas the public method on the prototype is only created once. If you have many privileged methods and you are creating A LOT of instances of your objects, you could see how this may not be desirable when it comes to memory usage.
I assume you are looking to hide some of your internal functionality from the outside world, so you will need to make use of privileged methods. For all your getters/setters, you will need to define them as privileged and add them to this (otherwise there isn't much point in creating getter/setters if you plan on leaving them private):
function SomeClass() {
// Private member
var _privateMember = 1;
// Public variable
this.publicMember = 1;
// Privileged getter method
this.getPrivateMember = function() {
return _privateMember;
};
// Privileged setter method
this.setPrivateMember = function(newVal) {
_privateMember = newVal;
};
// Private method that has access to '_privateMember' and 'this'
var _privateMethod = function() {
// Modify private member
_privateMember = 2;
// Modify public member
this.publicMember = 1;
// Do some other fancy processing privately
};
this.doSomethingAwesome = function() {
// Do some stuff here...
// Call your private method maybe?
_privateMethod();
};
}
// Public methods on prototype do not have access to private methods in your constructor
SomeClass.prototype.publicMethod = function() {
// Cannot access `_privateMember`
this.publicMember = 2; // Does have access to 'this'
};
As for your last question, about using a private vs. privileged method for modifying some private members... As you've said, you wouldn't be able to access it from the outside world which means it would be pretty useless unless you are adding other functionality to your private getter method, and exposing it to the outside world via a privileged method. If you do a lot of heavy lifting inside the constructor of your object, this could be a valid reason to create a reusable getter/setter method, but that really depends on your use case.
If this did not answer what your question was, or if you would like any other specific explanation about something feel free to ask.
I want to be able to create an object in Javascript that has public methods which can access the object's private members. However, I've heard that there's overhead in declaring public methods every time an object is created, so I'd prefer to avoid that overhead. So, for example, this code would do what I want:
function createMyObject(parameter) {
var that = {};
var privateVariable,
privateMethod = function () { return 1; };
that.publicVariable = 0;
that.publicMethod = function () {
privateVariable = privateMethod();
}
return that;
}
But everytime someone calls createMyObject, it has to create functions to set the public methods. If instead I do this:
function MyClass(parameter) {
var privateVariable,
privateMethod = function () { return 1; };
this.publicVariable = 0;
}
MyClass.prototype.publicMethod = function () {};
Here, I can avoid having to create new functions to set public methods everytime an object is constructed, but those public methods can't access the object's private members.
Is there some way to avoid the overhead of having to create new functions for public methods everytime an object is constructed, but also be able to let them have access to private members?
No, you can't.
A public method which is able to access private variables, is called privileged method.
From Private Members in JavaScript, by Douglas Crockford:
A privileged method is able to access the private variables and
methods, and is itself accessible to the public methods and the
outside. It is possible to delete or replace a privileged method, but
it is not possible to alter it, or to force it to give up its secrets.
Privileged methods are assigned with this within the constructor.
Then, you can't declare privileged methods using the prototype.
Using new Javascript features you can have truly private members. Basically you can use WeakMap to hide your members.
This is supported in Firefox and behind the "Experimental Javascript" flag in Chromium.
var MyClass = (function(){
var privmap = new WeakMap; // This holds our private members. Keep it secret.
function MyClass(){
var priv = {};
privmap.set(this, priv); // Add your private object for this instance.
this.notsec = "Anyone can access this!";
priv.secret = "Only code in this closure can see this!";
}
MyClass.prototype.secret = function MyClass_secret() {
var priv = privmap.get(this); // Get our private object.
return priv.secret; // Retrieve.
}
return MyClass;
})();
var o = new MyClass;
console.log(o.secret()); //-> Only code in this closure can see this!
By adding one line to the beginning of every function you can return your private object. I like to call it priv so that public members go on this and private on priv, nice and consistent.
This has the nice advantage that you only have a single instance of every method, instead of creating a closure for each instance.
Conside the following JavaScript code. The function definitions all seem to achieve the same thing. Is there any recommended convention for defining the functions which are then 'revealed' in the return dictionary object?
var testModule = (function(){
var counter = 0;
var localFunc1 = function() {
return "local 1";
}
function localFunc2() {
return "local 2";
}
this.localFunc3 = function() {
return "local 3";
}
localFunc4 = function() {
return "local 4";
}
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
})();
I don't think that there is any real preferred method. The most common setup I've seen involves creating all of your methods as local (using var) then returning an object that exposes the public methods.
A couple of things to note:
this.localFunc3 will only work if your object is instantiated with the 'new' keyword
when returning your object, remove the () from each function so that you are returning a reference to the function and not the function's returned value
localFunc4 will be global since it has no 'var' keyword in front of it
When working with a module pattern like this, I tend to go for something along the lines of:
var Obj = ( function () {
var private_static = 'this value is static';
return function () {
//-- create return object
var _self = {};
//-- create private variables
var private_variable = 'this value is private';
var func1 = function () {
return 'value 1';
};
//-- attach public methods
_self.func1 = func1;
//-- return the object
return _self;
};
} )();
Some notes about this method:
allows for private static variables (if you don't need private static variables, you can remove the closure)
by creating the _self reference first, you can pass a self reference to any objects instantiated from within that need a reference to their parent
I like that I can reference all internal functions without _self.whatever or this.whatever, ignoring whether or not they are private or public
The definitions do not achieve the exact same thing.
var localFunc1 and function localFunc2 do the same thing, they create functions only available inside your outer function.
this.localFunc3 and localFunc4 are not really local functions: they both belong to the window object (this in that context is window, and localFunc4 is declared without the var statement).
So, the latter two don't even need to be exposed on your returned object, since they're already global. And, actually, you are not exposing any functions on your return object, you are exposing their return values, since you invoke each of them. Were you trying to do this?
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
Note: I recommend you watch this video where Douglas Crockford explains the multiple ways to deal with inheritance in JavaScript. I believe you are looking for what he calls "parasitic inheritance".
Are there any downsides to using a JavaScript "class" with this pattern?
var FooClass = function()
{
var private = "a private variable";
this.public = "a public variable";
var privatefn = function() { ... };
this.publicfn = function() { ... };
};
var foo = new FooClass();
foo.public = "bar";
foo.publicfn();
What you're doing in your example isn't the "class" pattern people think of in JS -- typically people are thinking of the more "normal" class model of Java/C#/C++/etc which can be faked with libraries.
Instead your example is actually fairly normal and good JS design, but for completeness i'll discuss behaviour differences you'll see between the private and public "members" you have
var private = "a private variable";
this.public = "a public variable";
Accessing private from within any of your functions will be quite a lot faster than accessing public because the location of private can be determined reasonably well just with a static lookup by the JS engine. Attempts to access public require a lookup, most modern JS engines perform a degree of lookup caching, but it is still more expensive than a simple scoped var access.
var privatefn = function() { ... };
this.publicfn = function() { ... };
The same lookup rules apply to these functions as with the above variable accesses, the only real difference (in your example) is that if your functions are called, say privatefn() vs this.publicfn(), privatefn will always get the global object for this. But also if someone does
f = foo.publicfn;
f();
Then the call to f will have the global object as this but it will be able to modify the private variable.
The more normal way to do public functions however (which resolves the detached public function modifying private members issue) is to put public functions on the prototype, eg.
Foo.prototype.publicfn = function() { ... }
Which forces public functions to not modify private information -- there are some times where this isn't an option, but it's good practice as it also reduces memory use slightly, take:
function Foo1() {
this.f = function(){ return "foo" };
}
vs
function Foo2() {
}
Foo2.prototype.f = function(){ return "foo" };
In Foo1 you have a copy of the function object for every instance of Foo1 (not all the emory, just the object, eg. new Foo1().f !== new Foo2().f) whereas in Foo2 there is only a single function object.
That's good so far, but there's another access level you've left out.
this.publicfn is really a priveleged method as it has access to private members and functions.
To add methods which are public but not priveleged, modify the prototype as follows:
FooClass.prototype.reallypublicfn = function () { ... };
note that this method does not have access to private members of FooClass but it is accessible through any instance of FooClass.
Another way of accomplishing this is returning these methods from the constructor
var FooClass = function()
{
var private = "a private variable";
this.public = "a public variable";
var privatefn = function() { ... };
this.publicfn = function() { ... };
return {
reallypublicfn: function () { ...}
}
};
var foo = new FooClass();
foo.public = "bar";
foo.publicfn();
Basically, these methods of data hiding help you adhere to traditional OOP techniques. Generally speaking, improving data-hiding and encapsulation in your classes is a good thing. Ensuring low coupling makes it much easier to change things down the road, so publicly exposing as little as possible is really to your benefit.
See https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript for a simple overview and http://www.crockford.com/javascript/private.html for details on how to accomplish these things.
The main downside is that you'll wind up with a copy of publicfn for each instance of FooClass. If you'll be creating a lot of FooClass objects, it would be more efficient to
write
FooClass.prototype.publicfn = function() { ... };
It depends on your needs and relative performance. Javascript isn't the most type-safe language and isn't very strong with regards to member visibility. Traditionally you can have "private", "public privileged", and "public" visibility within a Javascript type.
You can declare private and public privileged members using:
function FooClass()
{
var privateVar = 1;
function privateFn()
{
return privateVar; // etc...
}
this.publicVar = 2;
this.publicFn = function()
{
return privateFn();
}
}
This example uses a function closure, which consists of a function declaration that includes values from the scope where the function is defined. This is acceptable when member visibility is necessary but can lead to overhead. The JavaScript interpreter cannot reuse the privateFn or publicFn definitions for every instantiation since they refer to variables or functions in the outer scope. As a result every instance of FooClass results in additional storage space for privateFn and publicFn. If the type is uses infrequently or in moderation the performance penalty is neglegible. If the type is used very often in the page, or if the page is more of an "AJAX" style where memory isn't freed as frequently since the page is not unloaded then the penalty can be more visible.
An alternative approach is to use prototype members. These are unprivleged public members. Since Javascript is not entirely type-safe and is relatively easy to modify after it's loaded, type safety and member visibility aren't as reliable for controlling access to type internals. For performance reasons, some frameworks like ASP.NET Ajax instead using member naming to infer visibility rules. For example, the same type in ASP.NET Ajax might look like:
function FooClass2()
{
this._privateVar = 1;
this.publicVar = 2;
}
FooClass2.prototype =
{
_privateFn : function()
{
return this._privateVar;
},
publicFn : function()
{
return this._privateFn();
}
}
FooClass2.registerClass("FooClass2");
In this case the private scoped members are private in name only, the "_" prefix is considered to mean a private member variable. It has the downside of preventing the member from being truly private, but the upside of allowing in-memory patching of the object. The other main benefit is that all functions are created once by the interpreter and engine and reused over and over for the type. The "this" keyword then refers to the instance of the type even though the function reference itself is the same.
One way to see the difference in action is to try this with both types (if you don't have ASP.NET Ajax, you can ignore the last line in FooClass2 that calls registerClass())
var fooA = new FooClass(), fooB = new FooClass();
alert(fooA.publicFn===fooB.publicFn); // false
var foo2A = new FooClass2(), foo2B = new FooClass2();
alert(foo2A.publicFn===foo2B.publicFn); // true
So its a matter of type safety and member visibility vs. performance and the ability to patch in memory
Also, if I may mention something useful to this - With prototype you are able to add additional methods later on in the code to extend the function from an extern scope. As a tiny benefit, the whole body with all the methods won't be rendered every time, hence it speeds up compiling performances. If you have all the declared methods inside the function already, this slightly would take more time to render. So, my advice, apply these later only when they become relevent in the current code.
Example:
// inside
function fn(arg) {
this.val = arg;
fn.prototype.getVal =()=> {
console.log(this.val);
}
}
var func = new fn('value');
func.getVal();
// declare extern methods
function fn2(arg) {
this.val = arg;
}
fn2.prototype.getVal =()=> {
console.log(this.val);
}
var func2 = new fn2('value');
func2.getVal();