Javascript namespacing - is this particular method good practice? - javascript

I'm a javascript newbie, and I've come up with the following scheme for namespacing:
(function() {
var ns = Company.namespace("Company.Site.Module");
ns.MyClass = function() { .... };
ns.MyClass.prototype.coolFunction = function() { ... };
})();
Company.namespace is a function registered by a script which simply creates the chain of objects up to Module.
Outside, in non-global scope:
var my = new Company.Site.Module.MyClass();
I'm particularly asking about the method by which I hide the variable ns from global scope - by a wrapping anonymous function executed immediately. I could just write Company.Site.Module everywhere, but it's not DRY and a little messy compared to storing the ns in a local variable.
What say you? What pitfalls are there with this approach? Is there some other method that is considered more standard?

You dont need to scope classes like that, its only necessary if you have global variables outside of the class. I use this approach...
MyApp.MyClass = function() {
};
MyApp.MyClass.prototype = {
foo: function() {
}
};
Also note that I use a object literal for a cleaner prototype declaration
However if you need to scope global variables then you can do
(function() {
var scopedGlobalVariable = "some value";
MyApp.MyClass = function() {
};
MyApp.MyClass.prototype = function() {
foo: function() {
}
};
})();

Your approach looks fine to me.
However, you can also do this slightly different, by returning the "class" from the self-executing function:
Company.Site.Module.MyClass = (function() {
var MyClass = function() { ... };
MyClass.prototype.foo = function() { ... };
return MyClass;
})();
This strips at least all the ns. prefixes. The namespace function can still be utilized to create the objects, but outside of the self-executing function.

Related

Object litterals vs Module pattern

I would like to understand clearly the difference between those two following patterns. In fact, the second one allows to mimic public and private method, but is there any other difference ?
var myModule = {
myProperty: "someValue",
...
myMethod: function () {
console.log( "Anything" );
}
};
myModule.myMethod();
and this :
var myModule = (function(){
var myProperty= "someValue";
...
return {
myMethod: function(){
console.log('something');
}
}
})();
myModule.myMethod();
The second one is essentially just like the first, except that it also provides for a closure around the object where "private" variables can be kept.
Specifically, if you set up an example like the second such that it had no local variables and no parameters to the anonymous function, it'd be exactly like not having the anonymous function at all.

prototype on single instances of functions

If I know that I only will create one instance of the MyClass function below, which of my two snippets below would you prefer? Should I stick with the latter, even though I know that I'll only create one instance of the function?
I know that prototype is useful from a performance perspective when sharing methods across all instances of a function, but in this case I would like to hear your input.
var MyClass = (function () {
var cls = function () { };
cls.prototype = {
init: function(data){
}
};
return cls;
})();
vs
var MyClass = (function () {
var cls = function () {
this.init = function(data){
}
};
return cls;
})();
Your second code snippet is a syntax error, you're trying to put a property initializer where a statement is expected. (Not anymore)
If you're only going to have a single object that you need the init function on, then:
var MyObject = {
init: function(data) {
// ...
}
};
Then you don't even need to call a function to create it, it's already there.
If you want to have truly private variables and such (which I assume is the reason for your outer anonymous functions), then:
var MyObject = (function() {
var trulyPrivateDataHere;
return {
init: function(data) {
// ...
}
};
})();
I prefer this because it's clear and direct: You're creating the actual object. I don't see any need for a constructor function if you're only ever going to create a single instance.
But if it has to be a constructor function, I guess I'd very marginally prefer your second option, because it's simpler, and simple is good barring the need for complexity.

Where should private methods be placed when using the JavaScript Module pattern?

I've started using the Module pattern in a project of mine. As I understand it, it goes something like this:
var obj = (function(foo){
//Some initialization logic up here.
//Private methods
var privateBazz = function(){
return "I'm known only to this closure!";
}();
//Public methods
return {
publicFoo: foo,
publicBar: function(){
return foo + privateBazz;
}
}
})();
This looked pretty good on paper and, in practice, seems to work reasonably well. Initialization logic at the top is intuitive, then private methods, then public.
I've encountered one issue, though. How should I call publicFoo or publicBar from outside the scope of the return statement and inside the scope of obj's function declaration?
My current solution is to do something like:
var obj = (function(foo){
//Private methods declared early for use.
var privateBazz = function(){
return "I'm known only to this closure!";
}();
var privateBar = function(){
return foo + privateBazz;
};
//Some initialization logic up here.
var dependentOnBar = privateBar();
//Public methods
return {
publicFoo: foo,
publicBar: privateBar
}
})();
This works, but suddenly the declarations of my private variables are placed above my objects private property declarations. The problem becomes exacerbated if I attempt to keep the private function declarations as close to the code which first calls them, so I have just been declaring all the private functions I need at the top, then initializing properties afterwards. Again, this works, but I am used to having code as close to the execution point as possible. So, declaring blocks of private functions at the top is really awkward to me. Does anyone else feel this way, or is this something I just need to get over for JavaScript? Are there any steps I should be taking when I see this happening?
It sounds like you could solve this problem by simply not using object notation to return the module, but rather initialize it and build it as you go. This would go something like this:
var obj = (function(foo){
var self = {};
//Some initialization logic up here.
//Private properties
var foo = "only accessible within this scope";
//Private methods
var privateBazz = function(){
return "I'm known only to this closure!";
}();
//Public Properties
self.publicFoo = foo;
//Public Methods
self.publicBar = function(){
return foo + privateBazz;
};
return self;
})();
here is my solution: if you declare everything before the return as a "private" method and make public those you want to, then you can call your private from within the public and vice versa (in your first sample, your privates can't call the publics as they are not declared at that moment)
var obj = (function() {
// All functions now have direct access to each other
var privateFunc = function() {
return "private "+publicFunc1();
};
var publicFunc1 = function() {
return "public 1 ";
};
var publicFunc2 = function() {
return "public 2 "+publicFunc1();
};
var publicFunc3 = function() {
return "public 3 "+privateFunc();
};
// Return the object that is assigned to Module
return {
publicFunc1: publicFunc1,
publicFunc3: publicFunc3,
publicFunc2: publicFunc2
};
}());
alert(obj.publicFunc3());
If you emulate CommonJS Modules, you can assign properties to the exports object as well as accessing them from elsewhere within the IIFE scope via qualified or unqualified name.
(function (exports, undefined) {
var priv1 = 42;
exports.pubOne = function () {};
var localAlias = function () {};
localAlias(42);
exports.pubTwo = localAlias;
})(window.App);
In this example, Window.App might be my namespaced global object for this module, but you could pass in an empty object or some deeply nested namespace just as easily.

Difference between two JavaScript object types

I see objects in JavaScript organized most commonly in the below two fashions. Could someone please explain the difference and the benefits between the two? Are there cases where one is more appropriate to the other?
Really appreciate any clarification. Thanks a lot!
First:
var SomeObject;
SomeObject = (function() {
function SomeObject() {}
SomeObject.prototype.doSomething: function() {
},
SomeObject.prototype.doSomethingElse: function() {
}
})();
Second:
SomeObject = function() {
SomeObject.prototype.doSomething: function() {
},
SomeObject.prototype.doSomethingElse: function() {
}
}
Both of those examples are incorrect. I think you meant:
First:
var SomeObject;
SomeObject = (function() {
function SomeObject() {
}
SomeObject.prototype.doSomething = function() {
};
SomeObject.prototype.doSomethingElse = function() {
};
return SomeObject;
})();
(Note the return at the end of the anonymous function, the use of = rather than :, and the semicolons to complete the function assignments.)
Or possibly you meant:
function SomeObject() {
}
SomeObject.prototype.doSomething = function() {
};
SomeObject.prototype.doSomethingElse = function() {
};
(No anonymous enclosing function.)
Second:
function SomeObject() {
}
SomeObject.prototype = {
doSomething: function() {
},
doSomethingElse: function() {
}
};
(Note that the assignment to the prototype is outside the SomeObject function; here, we use : because we're inside an object initializer. And again we have the ; at the end to complete the assignment statement.)
If I'm correct, there's very little difference between them. Both of them create a SomeObject constructor function and add anonymous functions to its prototype. The second version replaces the SomeObject constructor function's prototype with a completely new object (which I do not recommend), where the first one just augments the prototype that the SomeObject constructor function already has.
A more useful form is this:
var SomeObject;
SomeObject = (function() {
function SomeObject() {
}
SomeObject.prototype.doSomething = doSomething;
function doSomething() {
}
SomeObject.prototype.doSomethingElse = doSomethingElse;
function doSomethingElse()
}
return SomeObject;
})();
There, the functions we assign to doSomething and doSomethingElse have names, which is useful when you're walking through code in a debugger (they're shown in call stacks, lists of breakpoints, etc.). The anonymous function wrapping everything is there so that the doSomething and doSomethingElse names don't pollute the enclosing namespace. More: Anonymouses anonymous
Some of us take it further:
var SomeObject;
SomeObject = (function() {
var p = SomeObject.prototype;
function SomeObject() {
}
p.doSomething = SomeObject$doSomething;
function SomeObject$doSomething() {
}
p.doSomethingElse = SomeObject$doSomethingElse;
function SomeObject$doSomethingElse()
}
return SomeObject;
})();
...so that not only do we see doSomething, but SomeObject$doSomething in the lists. Sometimes that can get in the way, though, it's a style choice. (Also note I used the anonymous function to enclose an alias for SomeObject.prototype, to make for less typing.)
First off, both snippets will not parse for me (Chrome) - you should use = in place of :. That said, my humble opinion follows.
The latter snippet is slightly strange, because you actually define methods on SomeObject's prototype at the time of the object construction, rather than at the parse time. Thus, if you have re-defined some method on SomeObject.prototype, it will get reverted to the original version once a new object is constructed. This may result in unexpected behavior for existing objects of this type.
The former one looks fine, except that the (function { ...} ())() wrapper may not be necessary. You can declare just:
function SomeObject() {}
SomeObject.prototype.doSomething = function() {}
SomeObject.prototype.doSomethingElse = function() {}
The actual difference between first and second in your questions is just:
var o = (function () {})(); # call this (A)
and
var o = function () {}; # call this (B)
Unfortunately, neither of the examples that you gave are written correctly and, while I don't think either will actually give an error at parse-time, both will break in interesting ways when you try to do things with the result.
To give you an answer about the difference between (A) and (B), (A) is the immediate function application pattern. The JavaScript Patterns book has a good discussion, which I recommend.
The actual problems in your code have been explained by other people while I was writing this. In particular T.J. Crowder points out important things.

Writing a Javascript library that is code-completion and code-inspection friendly

I recently made my own Javascript library and I initially used the following pattern:
var myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
The problem with this is that I can't really use code completion because the IDE doesn't know about the properties that the function literal is returning (I'm using IntelliJ IDEA 9 by the way).
I've looked at jQuery code and tried to do this:
(function(window, undefined) {
var myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
window.myLibrary = myLibrary;
}(window));
I tried this, but now I have a different problem. The IDE doesn't really pick up on myLibrary either.
The way I'm solving the problem now is this way:
var myLibrary = {
func: function() { },
func2: function() { },
prop: ""
};
myLibrary = (function () {
var someProp = "...";
function someFunc() {
...
}
function someFunc2() {
...
}
return {
func: someFunc,
fun2: someFunc2,
prop: someProp;
}
}());
But that seems kinda clunky, and I can't exactly figure out how jQuery is doing it. Another question I have is how to handle functions with arbitrary numbers of parameters.
For example, jQuery.bind can take 2 or 3 parameters, and the IDE doesn't seem to complain. I tried to do the same thing with my library, where a function could take 0 arguments or 1 argument. However, the IDE complains and warns that the correct number of parameters aren't being sent in. How do I handle this?
EDIT
I'm starting to wonder if this is an Idea9 issue because jQuery has the same problem. I don't seem to have this problem in other projects though.
I'm using IDEA with yahoo module pattern and my autocomplete works. Google for yahoo module pattern.
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
http://ajaxian.com/archives/a-javascript-module-pattern
TEST = function() {
var SOME_CONSTANT='asd';
function privateStuff(){
var a = 'asd';
return a;
}
return{
someArray:[],
someMethod: function(foo, bar){
var foo = *1
}
,
myProperty:'test'
}
}();
TEST.*2
with *1 and *2 i marked places where i tried auto complete.
in *1 i get SOME_CONSTANT and privateStuff method, and if i put this.(autocomplete) i get access to all the methods and properties inside of return {} block
when i try autocomplete on *2 i get all the methods and properties inside return {} block.
SOME_CONSTANT and privateStuff method are invisibile there, because they are "private".
For me that level of autocomplete is quite fine.
I think will be great if you read something about Douglas Crockford. He is THE architect in yahou YUI framework. And after that you can have a better idea to how build a great framework. And for the parameter there are 2 options. 1.- send via object example
{ option :{ var1 : "value" , var2:"value"}, var3 : "value" }
And the you can check if the option exist.
The second one not to great is check if the parameter is undefined.
function foo(var1,var2){
var var1_this = null;
if(var1 != undefined)
var1_this = var1;
}
and just a comment why build a new javascript framework? use Prototype, JQuery, Mootols, YUI. why reinventing the wheel?
This is in reply to the comments to mwilcox's post.
That example will actually work. Since myLibrary is defined without var, it is automatically put into the global namespace and accessible as such. Through the closure created by the self-executing function, the private variables and methods are still accessible in the myLibrary methods. You can easily try this out by putting it into Firebug or Rhino.
These days, I do not tend to hide my variables, i.e. I use the Pseudoclassical pattern or the Prototypal pattern and prefix my intended private methods with an _:
// Pseudoclassical pattern
function Hello() {}
Hello.prototype = {
method1: function() {},
method2: function() {},
_pseudeoPrivate: function() {}
};
/* Prototypal pattern. To create multiple instances of this object,
you need a helper function such as
function beget(o) {
var F = function() {};
F.prototype = o;
return new F;
}
var instance = beget(world);
*/
var world = {
method1: function() {},
method2: function() {}
};
To prevent my code from polluting the global namespace, I have a build process that wraps my modules in a closure and exports the public api to the namespace. This technique is also used by jQuery. You can see that in their source code (look at intro.js & outro.js) on Github.
This would allow you to use a pattern that allows your IDE (or ctags with vim) to see your api, whilst also preventing the pollution of the global namespace.
I write my libraries like this:
function MyLibrary() {
// code
}
MyLibrary.prototype.memberFunc = function() {
// code
}
MyLibrary.prototype.memberVar = 5;
new MyLibrary();
This way, in Geany (which uses CTAGS) MyLibrary is well recognized (for the most part, for example, memberVar is recognized as a function) and autocompletion seems to work. I don't know about IDEA9, but you could try it this way (I have a hunch it's a bit more evolved than CTAGS).
I recommend that you don't use private variables, but I understand you want them hidden from the intellisense. This is how I would do it:
(function(){
var privateVar = "shhhh!";
var privateMethod = function(){}
myLibray = {
prop:42,
foo: function(){
return privateMethod()
},
bar: function(){
return privateVar;
}
}
})();
This way you can have your private stuff in a closure and your library should be accessible.
[ edited. I clumsily did not include myLibrary in the anonymous function and it could not see the private vars. oops. ]
BTW, my reasons for private variables being bad: http://clubajax.org/javascript-private-variables-are-evil/

Categories

Resources