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.
Related
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.
In JavaScript, classes are usually emulated through constructors. However, I'm curious as to how one can create an encapsulated class, i.e. a class that keeps some of it's members private.
The commonly seen way of creating a 'class' is as follows:
function MyClass(parameter) {
this.value = parameter;
}
MyClass.prototype.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction();
};
MyClass.prototype.myPrivateFunction = function() {
...
};
As you can see, in this example myPrivateFunction is actually public. One approach I've seen to solve this problem is the following:
function MyClass(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this);
}
function myPrivateFunction() {
...
}
}
This works; myPrivateFunction is inaccessible from the outside. But this approach has a problem - all functions in this 'class' are going to be copied across instances, instead of shared through the prototype. Also using privateFunction.call(this) everywhere isn't awesome.
Same goes for non-function members. How can I define a private instance-member in a class? What is the best and what is the most common approach? Is it acceptable to simply rely on a naming convention (such as beginning private function names with a _)?
You could create a scope to hide you private functions with an auto executing function.
Like:
(function(){
function myPrivateFunction(arg_a, arg_b) {
/* ... */
console.log("From priv. function " + this.value);
}
window.MyClass = function(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this, 'arg_a', 'arg_b');
}
}
})();
But then you need to use MyClass only after it is declared since now it is an function expression and not a function statement, but all instances of MyClass will share the same instance of myPrivateFunction. but you will need to use Function.prototype.call (as in myPrivateFunction.call(this, 'arg_a', 'arg_b'); to get the value of this keyword to match your instance.
If you do just myPrivateFunction('arg_a, 'arg_b'); the keyword this will point to the global object (window on browsers) or null if 'strict mode' is enabled.
Just a note: In my own code I don't do this but rely on naming conventions like MyClass.prototype._myPrivateFunction = function(){}; when not using some framework.
I've seen people trying to attempt implementation of private methods in JS. However they all have different issues, like this one: JavaScript private methods
I believe my attempt has some problems as well. But other than the overhead and caller is not allowed in strict mode, what are the problems with my implementation?
You can see an working example in jsfiddle: http://jsfiddle.net/rabbit_aaron/oqpen8c8/17/
the implementation is also pasted here:
var CLASS = function () {
this.publicFunctions = {};
this.PROTOTYPE = {};
var _class = function () {
this.constructor.apply(this, arguments);
};
_class.prototype = this.PROTOTYPE;
_class.prototype.validateAccess = CLASS.prototype.validateAccess;
_class.prototype.constructor = function () {};
_class.prototype.publicFunctions = this.publicFunctions;
this.finalClass = _class;
return this;
};
CLASS.prototype.validateAccess = function (caller) {
if (this.publicFunctions[caller] !== caller) {
throw 'Accessing private functions from outside of the scope';
}
return true;
};
CLASS.prototype.setConstructor = function (func) {
this.PROTOTYPE.constructor = func;
};
CLASS.prototype.addPrivateFunction = function (name, func) {
this.PROTOTYPE[name] = function () {
this.validateAccess(this[name].caller);
func.apply(this, arguments);
};
return this;
};
CLASS.prototype.addPublicFunction = function (name, func) {
this.PROTOTYPE[name] = func;
this.publicFunctions[this.PROTOTYPE[name]] = this.PROTOTYPE[name];
return this;
};
CLASS.prototype.getClass = function () {
return this.finalClass;
};
The first thing that comes to mind is that it is pretty simple to do the following in some code that gets loaded later on:
instanceOfSubClass.validateAccess = function (caller) {
return true;
}
This effectively overrides validation. Pretty much all private variable tricks that don't involve using nested scoping to hide variables suffer from this problem. Of course, this is a pretty specific thing to have to know to do, so it depends on what you are trying to protect against. If you just want to protect against yourself in the future, then this might work fine, but if you are publishing a library that will be interacting with code you don't write and you want to ensure that it will always behave properly, then this isn't the way to go.
I believe my attempt has some problems as well.
Yes.
But other than the overhead and caller is not allowed in strict mode
I wouldn't call that a problem, I'd call it a no-go. Strict mode is supposed to be the default mode.
what are the problems with my implementation?
About your approach of making methods "private":
It's easy to circumvent your measures. Like #Austion you can simply override the validateAccess function, but you can also mess with the public publicFunctions object
It's only hiding methods, not fields. Making non-function properties private is often the more relevant goal, as these are containing the (protection-deserving) state of the instance.
It doesn't work in engines that have no Function::toString decompilation (there are a few old ones). Also, it doesn't work for methods that are programmatically created (as closures) and share the same body.
A few bugs in your implementation that are possible to fix:
private methods can't return a value
private methods can't call other private methods, only public methods can call them
this.constructor.apply(this, arguments); is a nice idea to make a settable constructor. However, it a) will fail horribly once you try inheritance (can be fixed by by calling _class.prototype.constructor) and b) corrupts the rule of thumb that fn.prototype.constructor == fn/Object.getPrototypeOf(instance)==instance.constructor.prototype
Remember, true privacy is only possible through the use of closures.
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".
In our code base, I find that many developers use underscores as the first letter of a member variable to discourage public use. Normally, a better practice is just to declare a local variable that's accessible to an object's methods, but in our case, this doesn't seem possible because all the methods are defined on the prototype. Here's an example.
MyContrivedWidget = function(container) {
this._container = jQuery(container);
}
MyContrivedWidget.prototype = {
draw: function() {
var link = jQuery(document.createElement('a'))
.html('some contrived text')
.attr('href', '#')
.appendTo(this._container);
}
}
We have multiple reasons for using the prototype object, but the most compelling is probably that using the prototype chain allows for easy inheritance and overriding of methods. This is good for us because we have multiple products on one platform that may want to reuse a lot of JavaScript while overriding specific functionality.
So my question is, how can we get all the benefits of the prototype chain without allowing variables that should be private to be publicly accessible?
Simply spoken: ECMAscript edition 3 has no possibility to create "private" variables using prototypal inheritance or the prototype chain.
It's a little different in ES5. You've got methods like .defineProperties()help there which, are able to "hide" properties within an object.
But even if you hide the propertys from enumaration for instance, one would still be able to access those if he knows they are available. As you mentioned, the only real privacy in ECMAland is, to invoke closures. Better said, using a method-pattern by invoking a function(-context) which returns an object that contains methods as propertys. Those methods have access (since it's context closes over the parent context) to the declared variables in the outer (parent) scope. No other object can access those variables after. This looks like:
var Animal = function( args, priv, shared ) {
shared = shared || { };
shared.speed = 2;
shared.legs = 4;
shared.name = args.name || 'unknown';
priv = priv || {
run: function() {
console.log(shared.name, ' is running ', shared.speed, ' meters');
return this;
},
die: function() {
console.log(shared.name, ': wwuuaarhhhck.. aahahsd sd..aahsd.....');
return this;
}
};
return priv;
};
var Dog = function( args, priv, secret ) {
secret = secret || { };
priv = Animal( args, priv, secret ) || { };
priv.addSomeMethod = function() { };
return priv;
};
var bello = Dog({name: 'Bello'});
bello.die(); // "Bello: wwuuaarhhhck.. aahahsd sd..aahsd....."
There are some great patterns out there which bring this idea to an extend, which are also offer inheritance and shared objects + super methods. A good start to this kind of programming is still Douglas Crockfords "Javascript: the good parts".