I'm having problem with private variables in JavaScript's Revealing Prototype Pattern. I can't figure out how can I have private variables that are used in several different functions inside shared (singleton) prototype, without exposing them. Here is the example of what I mean in JSFiddle.
The problem is in using var v versus this.v. First one messes the state of all instances, but second is publicly visible. Is there a way to have v private, and preserve its state for each individual instance?
There is not a way to do that with the revealing prototype pattern.
You can only do that with something like this:
function MyClass() {
var v = 1;
this.getV = function() {
return v;
};
}
And that's why there are some die-hard enthusiasts for this kind of approach.
Personal option: Stick an underscore in front of it, and putting it on the object: this._v. Don't fight JavaScript; use it.
Related
I often use the pattern of a main JavaScript constructor function and adding methods to its prototype object so they can be called intuitively by the user, for example:
function Slideshow(options) {
this.options = options
this.slideshow = $('#slideshow')
//more variables here
}
Slideshow.method1 = function () {
this.slideshow.addClass('test') // do something with slideshow variable
};
Slideshow.method2 = function () {
// another method
};
The one thing that really bugs me about this pattern is how in order to make variables accessible across all prototype methods, I have to add "this" in front of each variable inside the constructor function. It's a major pain, and I can't help but think there's a more elegant way to do this.
If I forgo using the prototype object and just add the methods as instance methods, I know I can't get around this problem, but I like the efficiency? and self encapsulating nature of this pattern. Any other suggestions for a better pattern? Thanks!
It's a major pain
No, it's really not. Every single JavaScript developer uses this syntax. If you were in Ruby or Python, you'd use self., in PHP you'd use $this->. Some languages like C++ don't require any special decorator, but JavaScript does.
and I can't help but think there's a more elegant way to do this.
No, there isn't.
This is JavaScript's syntax, you cannot change it, and you cannot work around it. If you want to access a property of this, you need this. before the property name. Otherwise, you're talking about global variables.
If you want a different syntax, consider a different language like CoffeeScript, which compiles to JavaScript.
meager has pretty much summed things up if you're talking about accessing public instance properties or methods. You have to use this in front of it as that's just how the language works.
But, if you have private instance properties or methods, you can define those as local variables inside the constructor and you can access them without this.
function slideshow(options) {
// no need to resave the options arguments as they can be used
// directly from the argument variable
// define a per-instance private variable that other methods defined
// within the constructor can use directly without the use of `this`
var theShow = $(options.selector || '#slideshow');
// define public methods
this.method1 = function() {
// can access private instance variable here without this in front of it
theShow.addClass('test');
}
this.method2 = function() {
theShow.addClass(options.decoaration);
}
}
This general design pattern is described here: http://javascript.crockford.com/private.html
Practically speaking, this works because the constructor function with the public methods declared inside it creates a closure that lasts for the duration of the object lifetime so the local variables in the constructor become per-instance variables accessible only from the functions declared within the constructor.
This question already has answers here:
Defining methods via prototype vs using this in the constructor - really a performance difference?
(7 answers)
Closed 8 years ago.
I know it's possible to mimic private variables in JS:
function ConstructorPattern() {
var privateVar = 'hi there';
this.getVar = function() {
return privateVar;
};
};
But according to Learning JavaScript Design Patterns when referring to some similar code with class Car and method toString:
The above is a simple version of the constructor pattern but it does suffer from some problems. One is that it makes inheritance difficult and the other is that functions such as toString() are redefined for each of the new objects created using the Car constructor. This isn't very optimal as the function should ideally be shared between all of the instances of the Car type.
So the solution given in my case would be to add the getVar function via the prototype:
ConstructorPattern.prototype.getVar = function() {
return privateVar;
};
But of course that function has no idea what privateVar is so it doesn't work. I am aware of the module pattern but I specifically want to be able to instantiate multiple instances.
Is there any way to use the constructor pattern "properly" with prototypes while still getting "private" functionality?
EDIT: If there isn't a way to accomplish this, is it really that bad for methods to be redefined for each class instance? I've recently started working on a code base that takes this approach. It seems like the only thing I'm missing out on is inheritance?
EDIT2: Marking as a duplicate based on link from the accepted answer.
Is there any way to use the constructor pattern "properly" with prototypes while still getting "private" functionality?
No. This pattern with privileged functions is based on closure scope, and cannot work with shared functions. All privileged methods must be instance-specific.
If there isn't a way to accomplish this, is it really that bad for methods to be redefined for each class instance?
No. Modern JavaScript engines optimize this pattern very well. Sure, there's a little overhead but you won't notice in typical setups.
It seems like the only thing I'm missing out on is inheritance?
Inheritance is still possible, see Define Private field Members and Inheritance in JAVASCRIPT module pattern. Sure, derived subclasses cannot directly access private variables that are declared in a parent constructor, but usually they don't need to anyway.
When you're creating getVar on the object's prototype, it wont be called when you do something like:
objectName.getVar();
Because the prototype's methods come AFTER object methods. An example below will show you what i mean:
function Car() {
var privy = "hidden";
this.getPrivy = function() {
return privy;
}
}
Car.prototype = {};
Car.prototype.getPrivy = function() {
return 'i came from prototype';
}
var obj = new Car;
obj.getPrivy();
JS follows a call chain such as:
Object method -> prototype method -> prototype prototype method etc.... all the way back to Object.prototype. It stops and returns when a valid method is found. In your case, your instance's method comes BEFORE your prototype's method.
I've heard that one of the advantages of closures is the ability to create private properties for objects as follows.
function Func2(){
//A is a closure, kept alive after the Func2 has returned,
//After Func2 returns, A is only accessible by getA and setA (it's "private")
var A = 100;
return {
getA: function(){
return A;
},
setA: function(newA){
A = newA;
}
}
}
You can get and set the private property A of an object created with Func2 using the getter and setter functions...
var obj2 = Func2();
obj2.getA();
obj2.setA(200);
But what's the point of that if I can do the same thing using a regular constructor function?
function Func1(){
var A = 100; //A is a private property of any object created with the Func1 constructor
this.getA = function(){
return A;
};
this.setA = function(newA){
A = newA;
};
}
Accessing the private properties is done the same way...
var obj1 = new Func1()
obj1.getA();
obj1.setA(200);
As others have pointed out in the comments, a closure is created in both cases, and both will work.
I think the reason that the return approach is recommended for the module pattern is that the module pattern does not make use of Javascript's prototype chain, so it's unnecessary to use a regular constructor function that would create a new prototype (which isn't needed and would waste memory). In your example, objects created by Func2 would just have the default prototype of Object.prototype, whereas objects created by Func1 would have a prototype of Func1.prototype which in turn would have the prototype Object.prototype. Also, Func2 has the advantage that it will work with or without the new keyword (although it's best to avoid the new keyword if you're using the module pattern for the reasons I mentioned above). (I have seen some programmers complain about the fact that if a programmer forgets the new keyword in traditional OO Javascript, it can cause hard-to-detect bugs; I personally have never found this to be an issue though).
Another approach to private variables, as you're probably aware, is to simply prefix them with _, e.g.:
function Func1() {
this._A = 100;
}
Func1.prototype = {
constructor: Func1,
getA: function(){
return this._A;
},
setA: function(newA){
this._A = newA;
}
};
Personally I prefer this over the module pattern - the main goal of private variables is communication to other programmers, i.e. "this is an internal property; don't access it directly" - and the underscore prefix is a well-known convention. Private properties have never really been about 100% preventing access to those properties, just discouraging it (consider the fact that most programming languages allow you to access private properties using reflection if you really want to). And also, simply prefixing with an underscore allows you to easily have "protected" properties in addition to private ones (useful for sub-types / sub-classes). Making use of the prototype chain is also more memory-efficient, because you don't have multiple copies of the same functions for each instance.
But I do realize that in spite of the simplicity of the underscore naming convention, some programmers still prefer using the module pattern to really make private properties inaccessible from outside the closure. If you want to do that, then I'd recommend using the traditional module pattern, using the return statement as in your first example.
Another pattern you could consider, if you prefer to stick with the module pattern but still want to declare public properties as you go along (rather than in a return statement at the end), would be to create a new object and use that instead of this, e.g.:
function Func3(){
var obj = {};
var A = 100;
obj.getA = function(){
return A;
};
obj.setA = function(newA){
A = newA;
};
return obj;
}
(By the way, for private methods, as opposed to private data properties, the underscore prefix isn't a necessity even if you're using the prototypal approach. The code sample in this answer is an example of this.)
I have a few questions about using the Module Pattern for JavaScript programming. I have seen guides on the pattern that utilize it in 2 different ways. The first is like this:
This method is from CSS Tricks,
Module Pattern
var s,
NewsWidget = {
settings: {
numArticles: 5,
articleList: $("#article-list"),
moreButton: $("#more-button")
},
init: function() {
// kick things off
s = this.settings;
}
};
The second method, I will use the same code but in a different way.
var s,
NewsWidget = (function(){
// Any variables or functions in here are private
var privateVar;
// All variables or functions in returned object become public
return {
settings: {
numArticles: 5,
articleList: $("#article-list"),
moreButton: $("#more-button")
},
init: function() {
// kick things off
s = this.settings;
}
}
}());
Now looking at these two examples, my assumption would be to only use the latter method because of the ability to use private variables due to closures..? Am I correct? The first method does not use a closure and therefore is in the global memory scope and cannot have private members. Why is it then, that CSS Tricks and other people use the first method as an example when it does not seem to have any real purpose?
Secondly, I am curious how the Module Pattern handles multiple objects of the same type? Unlike the Factory Pattern which is used to get any number of JavaScript Objects, the Module Pattern just executes the anonymous function once, therefore if I have a Module called BlogPost that defines all the attributes of a blog post, then how can I create multiple instances of this object?
my assumption would be to only use the latter method because of the ability to use private variables due to closures..? Am I correct?
Yes. If you need private variables.
The first method does not use a closure and therefore is in the global memory scope and cannot have private members.
Notice however that even in the second example, the s variable is unnecessarily global.
Why is it then, that CSS Tricks and other people use the first method as an example when it does not seem to have any real purpose?
For simplicity. Either when you don't have local variables around (because you don't need them, or you did model private things as properties), or when the author just doesn't care. Or didn't bother to write down the implicit IEFE.
Secondly, I am curious how the Module Pattern handles multiple objects of the same type?
It does not. Modules are singletons. They can have constructors or factories as fields, though, when you need to instantiate module-related objects. Still, there is only ever one (global) module object.
Your first example is not a Module Pattern, its a simple Object Literal initializer.
Only the second example are a Module Pattern, first example doesn't give the possibility to define encapsulation of private member or function
Quoted from Learning JavaScript Design Patterns, this is the typical pattern(there is some variation):
In JavaScript, the Module pattern is used to further emulate the
concept of classes in such a way that we're able to include both
public/private methods and variables inside a single object, thus
shielding particular parts from the global scope. What this results in
is a reduction in the likelihood of our function names conflicting
with other functions defined in additional scripts on the page.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
I have been doing research to come up with a standardized Javascript coding style for my team. Most resources now recommend the "Module" pattern that involves closures, such as this:
var Module = function() {
someMethod = function() { /* ... */ };
return {
someMethod: someMethod
};
}();
and invoke it like Module.someMethod();. This approach seems to only work with methods that would be static in a traditional OOP context, for example repository classes to fetch/save data, service layers to make outside requests, and the like. Unless I missed something, the module pattern isn't intended to be used with data classes (think DTOs) that would typically need to be passed to/from the service methods to the UI glue code.
A common benefit I see cited is that you can have true private methods and fields in Javascript with the module pattern, but this can also be achieved along with being able to have static or instance methods with the "classical" Javascript style similar to this:
myClass = function(param) {
// this is completely public
this.publicProperty = 'Foo';
// this is completely private
var privateProp = param;
// this function can access the private fields
// AND can be called publicly; best of both?
this.someMethod = function() {
return privateProp;
};
// this function is private. FOR INTERNAL USE ONLY
function privateMethod() {
/* ... */
};
}
// this method is static and doesn't require an instance
myClass.staticMethod = function() { /* ... */ };
// this method requires an instance and is the "public API"
myClass.prototype.instanceMethod = function() { /* ... */ };
So I guess my question is what makes the Module Pattern better than the traditional style? It's a bit cleaner, but that seems to be the only benefit that is immediately apparent; in fact, the traditional style seems to offer the ability to provide real encapsulation (similar to true OOP languages like Java or C#) instead of simply returning a collection of static-only methods.
Is there something I'm missing?
Module Pattern can be used to create prototypes as well see:
var Module = function() {
function Module() {};
Module.prototype.whatever = function() {};
return Module
}();
var m = new Module();
m.whatever();
As the other poster said the clean global namespace is the reason for it. Another way to achieve this however is to use the AMD pattern, which also solves other issues like dependency management. It also wraps everything in a closure of sorts. Here's a great Introduction to AMD which stands for Asynchronous Module Definition.
I also recommend reading JavaScript Patterns as it thoroughly covers the reasons for various module patterns.
The module pattern above is pointless. All you are doing is using one closure to return a constructor with prototype. You could have achieved the same with:
function Module() {};
Module.prototype.whatever = function() {};
var m = new Module();
m.whatever();
In fact you would have saved one object (the closure) from being created, with the same output.
My other beef with the module pattern is it if you are using it for private encapsulation, you can only use it easily with singletons and not concrete classes. To create concrete classes with private data you end up wrapping two closers, which gets ugly. I also agree that being able to debug the underscore pseudo-private properties is a lot easier when they are visible. The whole notion of "what if someone uses your class incorrectly" is never justified. Make a clean public API, document it, and if people don't follow it correctly, then you have a poor programmer in your team. The amount of effort required in Javascript to hide variables (which can be discovered with eval in Firefox) is not worth the typical use of JS, even for medium to large projects. People don't snoop around your objects to learn them, they read your docs. If your docs are good (example using JSDoc) then they will stick to it, just like we use every 3rd party library we need. We don't "tamper" with jQuery or YUI, we just trust and use the public API without caring too much how or what it uses underneath.
Another benefit you forgot to mention to the module pattern, is that it promotes less clutter in the global namespace, ie, what people refer to when they say "don't pollute the global namespace". Sure you can do that in your classical approach, but it seems creating objects outside of anonymous functions would lend more easily to creating those objects in the global namespace.
In other words, the module pattern promotes self contained code. A module will typically push one object onto the global namespace, and all interaction with the module goes through this object. It's like a "main" method.
Less clutter in the global namespace is good, because it reduces the chances of collisions with other frameworks and javascript code.