I'm a bit confused, how can I create public and private members.
My code template so far is like:
(function()){
var _blah = 1;
someFunction = function() {
alert(_blah);
};
someOtherFunction = function() {
someFunction();
}
}();
You may want to use the Yahoo Module Pattern:
myModule = function () {
//"private" variables:
var myPrivateVar = "I can be accessed only from within myModule."
//"private" method:
var myPrivateMethod = function () {
console.log("I can be accessed only from within myModule");
}
return {
myPublicProperty: "I'm accessible as myModule.myPublicProperty."
myPublicMethod: function () {
console.log("I'm accessible as myModule.myPublicMethod.");
//Within myProject, I can access "private" vars and methods:
console.log(myPrivateVar);
console.log(myPrivateMethod());
}
};
}();
You define your private members where myPrivateVar and myPrivateMethod are defined, and your public members where myPublicProperty and myPublicMethod are defined.
You can simply access the public methods and properties as follows:
myModule.myPublicMethod(); // Works
myModule.myPublicProperty; // Works
myModule.myPrivateMethod(); // Doesn't work - private
myModule.myPrivateVar; // Doesn't work - private
You don't. You can rely on convention, prepending _ to your private attributes, and then not touching them with code that shouldn't be using it.
Or you can use the function scope to create variables that can't be accessed from outside.
In javascript every object member is public. Most popular way of declaring the private field is to use the underscore sign in it's name, just to make other people aware that this is private field:
a = {}
a._privateStuff = "foo"
The other way to hide the variable is using the scopes in javascript:
function MyFoo {
var privateVar = 123;
this.getPrivateVar = function() {
return privateVar;
}
}
var foo = new MyFoo();
foo.privateVar // Not available!
foo.getPrivateVar() // Returns the value
Here's the article that explains this technique in details:
http://javascript.crockford.com/private.html
Three things:
IIFEs:
It seems like you need to refresh your knowledge regarding this pattern. Have a look at this post before using an IIFE again.
Global public vs. Safe public:
Skipping var keyword with someFunction and someOtherFunction leads to registration of these function objects in the global scope, i.e., these functions can be called and reassigned from anywhere in the code. That could lead to some serious bugs as the code grows bigger in size. Instead, as Daniel suggested, use the module pattern. Though you can use other methods too like Constructors, Object.create(), etc, but this is pretty straightforward to implement.
/* create a module which returns an object containing methods to expose. */
var someModule = (function() {
var _blah = 1;
return {
someFunction: function() {},
someOtherFunction: function() {}
};
})();
/* access someFunction through someModule */
someModule.someFunction();
// ...
// ....
/* after 500+ lines in this IIFE */
/* what if this happens */
someFunction = function() {
console.log("Global variables rock.");
};
/* Fortunately, this does not interfere with someModule.someFunction */
Convention and scope combined:
We cannot expect from every developer to follow the underscore or the capitalization convention. What if one of them forgets to implement this technique. Instead of just relying upon the convention (_private, GLOBAL) and the scope (function scoping), we can combine both of them. This helps in maintaining consistency in coding style and provides proper member security. So, if next time somebody forgets to capitalize their globals, the console (in strict mode) can prevent the world from ending.
Javascript doesn't have true private members. You have to abuse scope if your really need privacy.
I hope this URL will solve your problem...see that...
http://robertnyman.com/2008/10/14/javascript-how-to-get-private-privileged-public-and-static-members-properties-and-methods/
Related
Background
I've been working with OOP style Javascript for the past few months, starting with just dissecting open source libraries. It seems like they mostly follow the same pattern, except that I've seen two ways of handling private functions, and I'm wondering which is the best (best as in best practice, or better for reasons I might not know about).
Example Code
Below is a very stripped down skeleton of the pattern I'm using. If you'll note, there are two different forms of private functions.
The first is attached to the prototype like public functions, but is prefixed with an _.
The second is just a function who's scope is only accessible by the class.
(function(window) {
window.FooBarClass = (function() {
var Class = function( params ) {
this._init( params );
}
/***************************************/
/************* INITIALIZE **************/
/***************************************/
Class.prototype._init = function( params ) {
// DO SETUP STUFF
};
/***************************************/
/********** PUBLIC FUNCTIONS ***********/
/***************************************/
Class.prototype.doThings = function() {
// DO STUFF
};
/***************************************/
/****** PRIVATE FUNCTIONS 1ST WAY ******/
/***************************************/
Class.prototype._createSection = function( params ) {
// DO STUFF
};
/***************************************/
/****** PRIVATE FUNCTIONS 2ND WAY ******/
/***************************************/
function correctTwoDigitYear( variable ) {
// DO STUFF
}
return Class;
}());
}(window));
Question
Which of these is preferable, and why?
JS doesn't actually have private methods, though as you've seen you can limit access to functions and variables by closing over their scope.
In the end, if it's on the prototype, it's not private--regardless of naming convention (leading underscores, etc). So if you really want to limit access to something, do NOT put it on the prototype.
The second pattern, putting functions in the local scope, is preferable because it's actually private. It's not really OOP though.
The first pattern, putting functions in underscored properties on the prototype, is preferable because they are actual methods that get their this passed implicitly like you expect of a method. By being instance methods, they are available to any module that needs them, instead of being restricted by scope, which can be beneficial in larger projects. And of course methods are important in OOP as they offer dynamic dispatch if you want to use polymorphism.
Also prototype methods are (were?) a bit better optimised, so they were chosen if you need to squeeze out the last bit of performance, though in practice you won't see much difference to a plain function call.
any method that is attached to the prototype property of a function is accessible by the object or by the child class. SO,
class.prototype.__init
cannot be considered as a private method.
It can be accesible by the object or it can be modified by extending the class
ex:
var someClass = (function () {
var Class = function( params ) {
this._init( params );
}
Class.prototype._init = function( params ) {
console.log("Hello World");
};
return Class;
} ());
var extendSomeClass = someClass;
extendSomeClass.prototype._init = function () {
console.log("Hey there");
}
var obj = new extendSomeClass(); // this wil print "Hey there"
In the example that you have posted, the _init is acting as a constructor, hence the property associated with it is made public (though the naming convention suggests a private member). But to follow a private access, a closure scope should be the best practice.
example:
var fooClass = (function () {
var Class = function () {
if(this._init) {
this._init.apply(this, arguments);
}
}
Class.prototype.hello = function () {
log("hello world");
}
function log(args) {
console.log(args);
}
}());
In the example above the function log is a private method and cannot be modified/overridden outside the scope.
I am trying to wrap my head around different Module pattern declinations. I see different ways of writing these modules and exposing their data.
I'm expecting information on advantages/disadvantages, better patterns not described here, use cases for each of them.
A) Object literal wrapped in a self invoking function, firing off with an init method: (source)
(function() {
var MyModule = {
settings: {
someProperty: 'value';
}
init: function() {
someMethod();
}
someMethod: function() {
// ...
}
};
MyModule.init();
})();
This is an example of a simple "Tweet This" utility I built. Am I using this pattern correctly? So far it's the only one that I have actual experience in writing.
B) Module as a namespaced self-invoking anonymous function: (source)
var MyModule = (function () {
var MyObj = {}
function privateMethod() {
// ...
}
MyObj.someProperty = 1;
MyObj.moduleMethod = function () {
// ...
};
return MyObj;
}());
Are there any advantages/disadvantages over the previous style? Also, what would be the implications of using object literal notation here instead of the dot syntax in the example? Object literal seems cleaner and easier, but I'm not really aware of the proper use cases for each?
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block: (source)
var MyModule = (function() {
var myPrivateVar, myPrivateMethod;
myPrivateVar = 0;
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
myPublicVar: "foo",
myPublicFunction: function(bar) {
myPrivateVar++;
myPrivateMethod(bar);
}
};
})();
Similar to the previous style, but instead of exposing an entire object with all of it's properties/methods, we're just exposing specific bits of data through a return statement.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword: (source)
(function(window, undefined) {
function MyModule() {
this.myMethod = function myMethod() {
// ...
};
this.myOtherMethod = function myOtherMethod() {
// ...
};
}
window.MyModule = MyModule;
})(window);
var myModule = new MyModule();
myModule.myMethod();
myModule.myOtherMethod();
I'm assuming the strength of this pattern is if the module is a 'template' of sorts where multiple entities may need to exist within an application. Any specific examples of a good use case for this?
All of these are using the same pattern just in slightly different ways.
A) Object literal wrapped in a self invoking function, firing off with an init method:
This is fine if you don't intend to allow anyone else to access a chunk of code. You don't even have to have an init function. Wrapping your code in an IIFE (immediately invoked function expression) prevents global namespace pollution and allows the use of "private" variables. In my opinion, this is just good practice, not a module.
B) Module as a namespaced self-invoking anonymous function:
This is what people mean when they're talking about the module pattern. It gives you private variables and functions then exposes those through a public interface. That interface just so happens to be called MyObj in your example.
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block:
This is actually exactly the same thing a B. The only difference is that methods on the interface can't directly reference the interface itself like you can in B. Example:
MyObj.methodA = function() {
return MyObj.methodB();
};
That will work with the previous example because you have a name to reference it but is only useful when you expect public methods to be called using anything other than the returned object as the execution context. i.e, setTimeout(MyModule.methodA) (that will be called with the global context so this.methodB() would not work as intended.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword:
Same thing as the previous 2 except for 2 minor differences. window is passed as an argument because it has historically been true that it's faster to access a local variable than a global variable because the engine doesn't have to climb up the scope chain. However, most JS engines these days optimize accessing window since it's common and a known object. Likewise, undefined is given as a parameter with nothing passed as an argument. This ensures you have a correct undefined value. The reasoning behind this is that technically, you can assign any value to undefined in non-strict mode. Meaning some 3rd party could write undefined = true; and suddenly all of your undefined checks are failing.
The other difference is that you're returning a function instead of an object. The bonus behind this is that you can have private variables which are shared in each instance of an object, as well as private variables per instance. Example:
var count = 0;
function MyObject(id) {
var myID = id;
count++;
// Private ID
this.getID = function() {
return myID;
};
// Number of instances that have been created
this.getCount = function() {
return count;
};
}
The downside to this is that you aren't attaching methods to the prototype. This means that the JS engine has to create a brand new function for every single instance of the object. If it was on the prototype, all instances would share the same functions but could not have individual private variables.
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.
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();