In a project I am working on I am structuring my code as follows
MyLib = {
AField:0,
ASubNamespace:{
AnotherField:"value",
AClass:function(param) {
this.classField = param;
this.classFunction = function(){
// stuff
}
}
},
AnotherClass:function(param) {
this.classField = param;
this.classFunction = function(){
// stuff
}
}
}
and so on like that to do stuff like:
var anInstance = new MyLib.ASubNamespace.AClass("A parameter.");
Is this the right way to go about achieving namespacing? Are there performance hits, and if so, how drastic? Do performance degradations stack as I nest deeper? Are there any other issues I should be aware of when using this structure?
I care about every little bit of performance because it's a library for realtime graphics, so I'm taking any overhead very seriously.
I suggest namespacing is a critical part of writing maintainable JavaScript - especially if you work with a team of developers.
Performance issues related to namespacing should be minimal if you compress/minimize your code on the way to production.
Here is an SO discussion of alternative ways to use namespaces.
When you structure your code as a big giant object-property hierarchy, you sometimes have issues where MyNamespaceObj.prop1 isn't available to MyNamespaceObj.prop2 yet. And then there's the fact that you often end up typing fully qualified names a lot throughout the code.
I'm starting to find I prefer doing something like this:
MyNamespaceObj = (function () {
// lots of code/definitions that have local scope
var internallyDefinedItem1 = function (n) { /* ... */ }
var internallyDefinedItem2 = {
foo: internallyDefinedItem1(532),
bar: totallyPrivateNeverExportedFunction(17)
}
var totallyPrivateNeverExportedVar = 'blahblahblah';
function totallyPrivateNeverExportedFunction (x) {
/* ... */
}
return {
exportedItem1: internallyDefinedItem1,
exportedItem2: internallyDefinedItem2,
...
}
})();
Namespacing your JavaScript is critical to avoid potential conflicts and overwrites. This is specially true when your JS will land up in foreign environments where external JS can also reside.
With that said, there is a performance hit because of namespacing, simply because the interpreter now has to follow a longer chain to access the required function/property.
For example, something like
var myProperty;
is accessed a little faster as compared to :
myNameSpace.module1.myProperty;
I think the difference in speed is not much unless you namespace extremely deeply and the advantage of avoiding potential conflicts is a big plus of namespacing.
But still, it is always good to keep this issue in mind.
Related
I've been using the following model for Namespacing my newest Scripts. So far, it has some distinct advantages that, while I'm sure could be replicated in other ways, really help to in my coding process. Unfortunately, I've come across a significant disadvantage... When using some JS compression utilities, they mangle the code badly enough that I must avoid many advantageous options. Luckily, the code I save with this model helps mitigate the "damages".
I'm still curious to know if there is a more viable solution as the min.js only fail consistently in Chrome/IE. I know the below is a little too abstract for some. Are there any experts that might point me in the right direction. I've used YUI, Packer and JSMin. JSMin works reliably, but is not nearly as efficient...
/* Global Namspace */
(function (T) {"use strict";
/* Top.Sub1 */
(function(S1) {
// ... Some methods (public/private)
/* Top.Sub1.Mini */
(function(M) {
// ... Some methods (public/private)
}(S1.Mini = S1.Mini || function(o){}));
}
(T.Sub1 = T.Sub1 || function(o){}));
/* Top.Sub2 */
(function(S2) {
// ... Some methods (public/private)
/* Top.Sub2.Mini1 */
(function(M1) {
// ... Some methods (public/private)
}(S2.Mini1 = S2.Mini1 || function(o) {}));
/* Top.Sub2.Mini2 */
(function(M2) {
// ... Some methods (public/private)
}(S2.Mini2 = S2.Mini2 || function(o) {}));
} (T.Sub2 = T.Sub2 || function(o) {}));
} (window.Namespace = window.Namespace || function(o){}));
UPDATE: The most common error I am faced with is "unexpected token" of various sorts.. sometimes a ')' and sometimes a '}'. Every once in a while, it is a '('. I haven't yet addressed gzip as I want this out of the way.
UPDATE 2: Have checked/removed ns with a Tidied-jsHint passing file and still does not minify correctly. It definitely has to do with this model... Does anyone have a clear answer as to why? If not, further recommendations are welcome. P.S. the Github has been updated with Tidied-jsHint passing code.
I'd say read this article about what needs to be done and what needs to be avoided for good minification – http://alistapart.com/article/javascript-minification-part-II
And then choose a proper modules framework like AMD or commonjs.
UPD. My main advice will be to use a linter on your code like http://jshint.com and adhere to a coding style like http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml It mostly comes with explanations of why something will break in certain sitautions. It's also going to make your code more approachable for open source contributors.
After testing nearly every option on every minifier I could get my hands on, the code minifies quite fine. (With and without the tidy, etc...) The issue comes when any of the minifiers try to replace or obfuscate symbols. In particular, it does not handle this for loop well:
for (i = 0; i < l; i++) {
_.points[i] = new S.Point(_, pts[i]);
}
Removal of the loop allows for the optimization to occur correctly.
I have been trying out some different ways to organize my code in my javascript applications and i wonder which one is the most appropriate.
First example:
var Application = {
init: function() {
//Some code
Calculate();
},
Calculate: function() {
//Some code
}
};
Second example:
(function() {
function init() {
//Some code
Calculate();
}
function Calculate() {
//Some code
}
})();
Third example:
(function() {
var init = function() {
//Some code
Calculate();
};
var Calculate = function() {
//Some code
};
})();
Or is it some other way that is preferred? I get very confused over this. Thanks in advance!
The answer is, without question, "it depends." How big is your application? Do you need all of the modules all of the time? How scalable and reusable does your app need to be? These are not JavaScript questions specifically, but rather "architectural" questions, and while learning JavaScript basics is relatively easy, it takes a lot of years to learn to be a good architect in software development. (though it is excellent that you are asking these questions.)
I would encourage you to dive into programming patterns. Learning patterns is learning to structure an application in the right way, depending on the given application.
I can say that a combination of your first example and your second example are a good place to start (an instantly invoked function expression wrapping and returning an object literal). This gives a degree of private scope via closure, and is called the Module Pattern. You will see this pattern used to some degree in almost all major JS applications and libraries because of its versatility and elegance.
To learn more about JavaScript patterns, I highly recommend Addy Osmani's "Learning JavaScript Design Patterns." You can read it for free, here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/
EDIT
thx to all the answers,
and finally I decide to use some tools like Step,
all I need is "flow control" and don't want any thing else which may slow down the performance (I don't know how much exactly it would effect or the effect just can be ignored).
So I just create a little tool for flow control:
line.js
/**
* Create the "next" function
*
* #param {Array} tasks
* #param {Number} index
* #param {Number} last
*/
var next = function(tasks, index, last) {
if (index == last) {
return tasks[index + 1];
}
else {
return function(data) {
var nextIndex = index + 1;
tasks[nextIndex](next(tasks, nextIndex, last), data);
};
}
};
/**
* Invoke functions in line.
*/
module.exports = function() {
var tasks = arguments,
last = tasks.length - 2;
tasks[0](next(tasks, 0, last));
};
usage:
var line = require("line.js");
line(function(next) {
someObj.find(function(err, docs) {
// codes
next(docs);
});
}, function(next, docs) {
// codes
});
Hope this helps.
EDIT END
As all know,
Node's built-in or third-part modules often provides async API,
and using "callback" function for dealing the results.
It's cool but sometimes would code like this:
//some codes
}
}
}
}
codes like this are hard to read.
I know "deferred" library can solve such problem,
Is there any good "deferred" module for Node?
And How is the performance if I code Node with "deferred"?
It is a large problem with Node-based code; you frequently grow "callback pyramids". There are several approaches to dealing with the problem:
Code style:
Use this annoyance as an opportunity to break your code into bite sized chunks. It means you're likely going to have a proliferation of tiny named funcs - that's probably just fine, though! You might also find more opportunities for reuse.
Flow-control Libraries
There are exactly 593.72 billion flow control libraries out there. Here's some of the more popular ones:
Step super basic serial & parallel flow management.
seq is a heavier but more feature-full flow control library.
There's plenty more. Search the npm registry for "flow" and "flow control" (sorry, doesn't appear to be linkable)
Language Extensions
There are several attempts to provide a more synchronous-feeling syntax on top of JavaScript (or CoffeeScript), often based on the concepts behind the tame paper.
TameJS is the OkCupid team's answer to this.
IcedCoffeeScript they've also ported TameJS over CoffeeScript as a fork.
streamline.js is very similar to TameJS.
StratifiedJS is a heavier approach to the problem.
This route is a deal-breaker for some:
It's not standard JavaScript; if you are building libraries/frameworks/etc, finding help will be more difficult.
Variable scope can behave in unexpected ways, depending on the library.
The generated code can be difficult to debug & match to the original source.
The Future:
The node core team is very aware of the problem, and are also working on lower level components to help ease the pain. It looks like they'll be introducing a basic version of domains in v0.8, which provide a way of rolling up error handling (avoiding the common return err if err pattern, primarily).
This should start to lay a great foundation for cleaner flow control libraries, and start to pave the way for a more consistent way of dealing with callback pyramids. There's too much choice out there right now, and the community isn't close to agreeing on even a handful of standards yet.
References:
Mixu's Node book has an awesome chapter on this subject.
There are tons of "deferred libraries". Have a look there http://eirikb.github.com/nipster/#promise and there http://eirikb.github.com/nipster/#deferred. To pick one, it's only a matter of style & simplicity :)
If you really don't like that, there's always the alternative of using named functions, which will reduce the indentation.
Instead of
setTimeout(function() {
fs.readFile('file', function (err, data) {
if (err) throw err;
console.log(data);
})
}, 200);
You can do this:
function dataHandler(err, data)
{
if (err) throw err;
console.log(data);
}
function getFile()
{
fs.readFile('file', dataHandler);
}
setTimeout(getFile, 200);
The same thing, no nesting.
There are some libraries that may be useful in some scenarios, but as a whole you won't be excited after using them for everything.
According to the slowness issues. Since node.js is async, the wrapped functions are not such a big performance consumer.
You could look here for deferred-like library
https://github.com/kriszyp/node-promise
Also this question is very similar
What nodejs library is most like jQuery's deferreds?
And as a final bonus I suggest you take a look at CoffeeScript. It is a language, which compiles to javascript and has more beautiful syntax, since the function braces are removed
I usually like to use the async.js library as it offers a few different options on how to execute the code
I will not add any code in here. Just working on a project and not only this time, but frequently one javascript file kills the others, so I ussually in this situation looked for similar solution (lets say a different slider and etc.)
But are there any more ways to wrap up some how a javascript file that it wont interfere with the others?
Please provide more details of what exactly you mean - but I have a feeling.
Use namespaces.
If you're using a collective of different libraries it could happen that libraries have the same global name, if you're not using namespaces.
Example how collisions usually occur:
function dontdothis() {
alert("Foo");
}
function dontdothis() {
alert("Bar");
}
dontdothis();
Example how to avoid those collisions:
var myownspace={};
myownspace.dothis=function() {
alert("Foo");
}
function dothis() {
alert("Bar");
}
myownspace.dothis();
In general, each desecrate chuck of JavaScript should be wrapped in a closure with an API that is exposed to the wide world through a single global (which has a non-generic name, so YAHOO is reasonable as it is unlikely to be used by something else, while $ is awful).
This is known as namespacing
If I understood your question correctly, your solution is namespaces.
var APP = {};
APP.namespace = function(sNamespace) {
if ("undefined" == typeof APP[sNamespace]) {
APP[sNamespace] = {};
}
}
Usage:
APP.namespace("profile");
APP.profile.AskQuestionDialog = function(oConfigs) { ... }
DOM tree:
-window
-APP
-profile
And you should define you namespace in beginning of each file using APP.namespace()
i've been playing with MVC for a while now, but since the project i'm on is starting to get wind in its sails more and more people are added to it. Since i'm in charge of hacking around to find out some "best practice", i'm especially wary about the possible misuses of javascript and would like to find out what would be the best way to have our views and partial views play nicely with javascript.
For the moment, we're having code that looks like this (only simplified for example's sake)
<script type="text/javascript">
function DisableInputsForSubmit() {
if ($('#IsDisabled').is(':checked')) {
$('#Parameters :input').attr('disabled', true);
} else {
$('#Parameters :input').removeAttr('disabled');
}
}
</script>
<%=Html.SubmitButton("submit", Html.ResourceText("submit"), New With {.class = "button", .onclick = "DisableInputsForSubmit(); if ($('#EditParameters').validate().form()) {SetContentArea(GetHtmlDisplay('SaveParameters', 'Area', 'Controller'), $('#Parameters').serialize());} return false;"})%><%=Html.ResourceIcon("Save")%>
Here, we're saving a form and posting it to the server, but we disable inputs we don't want to validate if a checkbox is checked.
a bit of context
Please ignore the Html.Resource* bits, it's the resource management
helpers
The SetContentArea method wraps ajax calls, and GetHtmlDisplay
resolves url regarding an area,
controller and action
We've got combres installed that takes care of compressing, minifying
and serving third-parties libraries and what i've clearly identified as reusable javascript
My problem is that if somebody else defines a function DisableInputsForSubmit at another level (let's say the master page, or in another javascript file), problems may arise.
Lots of videos on the web (Resig on the design of jQuery, or Douglas Crockford for his talk at Google about the good parts of javascript) talk about using the namespaces in your libraries/frameworks.
So far so good, but in this case, it looks a bit overkill. What is the recommended way to go? Should i:
Create a whole framework inside a namespace, and reference it globally in the application? Looks like a lot of work for something so tiny as this method
Create a skeleton framework, and use local javascript in my views/partials, eventually promoting parts of the inline javascript to framework status, depending on the usage we have? In this case, how can i cleanly isolate the inline javascript from other views/partials?
Don't worry and rely on UI testing to catch the problem if it ever happens?
As a matter of fact, i think that even the JS code i've written that is in a separate file will benefit from your answers :)
As a matter of safety/best practice, you should always use the module pattern. If you also use event handlers rather than shoving javascript into the onclick attribute, you don't have to worry about naming conflicts and your js is easier to read:
<script type="text/javascript">
(function() {
// your button selector may be different
$("input[type='submit'].button").click(function(ev) {
DisableInputsForSubmit();
if ($('#EditParameters').validate().form()) {
SetContentArea(GetHtmlDisplay('SaveParameters', 'Area','Controller'), $('#Parameters').serialize());
}
ev.preventDefault();
});
function DisableInputsForSubmit() {
if ($('#IsDisabled').is(':checked')) {
$('#Parameters :input').attr('disabled', true);
} else {
$('#Parameters :input').removeAttr('disabled');
}
}
})();
</script>
This is trivially easy to extract into an external file if you decide to.
Edit in response to comment:
To make a function re-usable, I would just use a namespace, yes. Something like this:
(function() {
MyNS = MyNS || {};
MyNS.DisableInputsForSubmit = function() {
//yada yada
}
})();