将光标移到/点击文章中的句子上,可以查看译文。      显示繁体中文内容    显示简体中文内容

Commonly accepted best practices around code organization in JavaScript
JavaScript通常的公认的最佳实践代码

As JavaScript frameworks like jQuery make client side web applications richer and more functional, i've started to notice one problem...

how in the world do you keep this organized?

  • Put all your handlers in one spot and write functions for all the events?
  • Create function/classes to wrap all your functionality?
  • Write like crazy and just hope it works out for the best?
  • Give up and get a new career?

I mention jQuery, but it's really any JavaScript code in general.i'm finding that as lines upon lines begin to pile up, it gets harder to manage the script files or find what you are looking for.quite possibly the biggest propblems i've found is there are so many ways to do the same thing, it's hard to know which one is the current commonly accepted best practice.

Are there any general recommendations on the best way to keep your .js files as nice and neat as the rest of your application?or is this just a matter of IDE?is there a better option out there?


EDIT

This question was intended to be more about code organization and not file organization.there has been some really good examples of merging files or splitting content around.

My question is : what is the current commonly accepted best practice way to organize your actual code?what is your way, or even a recommended way to interact with page elements and create reuseable code that doesn't conflict with each other?

Some people have listed namespaces which is a good idea.what are some other ways, more specifically dealing with elements on the page and keeping the code organized and neat?

时间:

It would be a lot nicer if javascript had namespaces built in, but i find that organizing things like Dustin Diaz describes here helps me a lot.


var DED = (function() {

 var private_var;

 function private_method()
 {
//do stuff here
 }

 return {
 method_1 : function()
 {
//do stuff here
 },
 method_2 : function()
 {
//do stuff here
 }
 };
})();

I put different"namespaces"and sometimes individual classes in separate files.usually i start with one file and as a class or namespace gets big enough to warrant it, i separate it out into its own file.using a tool to combine all you files for production is an excellent idea as well.

I try to avoid including any javascript with the HTML.all the code is encapsulated into classes and each class is in its own file.for development, i have separate <script> tags to include each js file, but they get merged into a single larger package for production to reduce the overhead of the HTTP requests.

Typically, i'll have a single 'main 'js file for each application.So, if i was writing a"survey"application, i would have a js file called"survey.js".this would contain the entry point into the jQuery code.i create jQuery references during instantiation and then pass them into my objects as parameters.this means that the javascript classes are 'pure 'and don't contain any references to CSS ids or classnames.


//file: survey.js
$(document).ready(function() {
 var jS = $('#surveycontainer');
 var jB = $('#dimscreencontainer');
 var d = new DimScreen({container: jB});
 var s = new Survey({container: jS, DimScreen: d});
 s.show();
});

I also find naming convention to be important for readability.for example : i prepend 'j 'to all jQuery instances.

In the above example, there is a class called DimScreen.(Assume this dims the screen and pops up an alert box.) it needs a div element that it can enlarge to cover the screen, and then add an alert box, so i pass in a jQuery object.jQuery has a plug-in concept, but it seemed limiting (e.g.instances are not persistent and cannot be accessed) with no real upside.so the DimScreen class would be a standard javascript class that just happens to use jQuery.


//file: dimscreen.js
function DimScreen(opts) { 
 this.jB = opts.container;
//...
};//need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
 var me = this;
 me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
//...
};

I've built some fairly complex appliations using this approach.

The code organization requires adoption of conventions and documentation standards :
1. Namespace code for a physical file ;

 
Exc = {};

 


2. Group classes in these namespaces javascript ;
3. Set Prototypes or related functions or classes for representing real-world objects ;


Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
 this.mask = mask;
. . .
};
Exc.ui.domTips = function (dom, tips) {
 this.dom = gift;
 this.tips = tips;
. . .
};


4. Set conventions to improve the code.for example, group all of its internal functions or methods in its class attribute of an object type.


Exc.ui.domTips = function (dom, tips) {
 this.dom = gift;
 this.tips = tips;
 this.internal = {
 widthEstimates: function (tips) {
. . .
 }
 formatTips: function () {
. . .
 }
 };
. . .
};


5. Make documentation of namespaces, classes, methods and variables.where necessary also discuss some of the code (some FIs and Fors, they usually implement important logic of the code).


/**
 * Namespace <i> Example </i> created to group other namespaces of the"Example". 
 */
Exc = {};
/**
 * Namespace <i> ui </i> created with the aim of grouping namespaces user interface.
 */
Exc.ui = {};

/**
 * Class <i> maskdInput </i> used to add an input HTML formatting capabilities and validation of data and information.
 * @ Param {String} mask - mask validation of input data.
 */
Exc.ui.maskedInput = function (mask) {
 this.mask = mask;
. . .
};

/**
 * Class <i> domTips </i> used to add an HTML element the ability to present tips and information about its function or rule input etc..
 * @ Param {String} id - id of the HTML element.
 * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id <i> </i>.
 */
 Exc.ui.domTips = function (id, tips) {
 this.domID = id;
 this.tips = tips;
. . .
};


These are just some tips, but that has greatly helped in organizing the code.Remember you must have discipline to succeed!

Dojo had the module system from the day one.in fact it is considered to be a cornerstone of Dojo, the glue that holds it all together :

Using modules Dojo achieves following objectives :

  • Namespaces for Dojo code and custom code ( dojo.declare() ) — do not pollute the global space, coexist with other libraries, and user's non-Dojo-aware code.
  • Loading modules synchronously or asynchronously by name ( dojo.require() ).
  • Custom builds by analyzing module dependencies to create a single file or a group of interdependent files (so-called layers) to include only what your web application needs.Custom builds can include Dojo modules and customer-supplied modules as well.
  • Transparent CDN-based access to Dojo and user's code.both AOL and Google carry Dojo in this fashion, but some customers do that for their custom web applications as well.
...