如何构build我的JavaScript / jQuery代码?
我正在用一个非常强大的基于Ajax的jQuery Web应用程序。 现在我已经到了几乎没有什么事件会触发什么行动的轨迹了。
我有点感觉,我的JavaScript结构是错误的,在一个更基本的水平。 你们如何构build您的JavaScript / jQuery代码,事件处理等,任何build议新手JavaScript开发人员。
AMDS!
第一个答案发布到这个问题已经有一段时间了,许多事情已经改变了。 首先,JS浏览器世界似乎正朝着代码组织的AMD(asynchronous模块定义)迈进。
工作的方式是将所有的代码写成AMD模块,例如:
define('moduleName', ['dependency1', 'dependency2'], function (dependency1, dependency2) { /*This function will get triggered only after all dependency modules loaded*/ var module = {/*whatever module object, can be any JS variable here really*/}; return module; });
然后模块使用AMD加载器如curl.js或require.js等加载,例如:
curl( [ 'myApp/moduleA', 'myApp/moduleB' ], ).then( function success (A, B) { // load myApp here! }, function failure (ex) { alert('myApp didn't load. reason: ' + ex.message); } );
优点是:
-
你只需要在你的页面上加载一个加载AMD加载器的单个
<script>
元素(其中一些非常小)。 -
之后,所有的JS文件将被自动提取asynchronous非阻塞! 时尚,因此方式更快!
-
必要的模块只有在依赖被加载后才能被执行。
-
模块化(这意味着代码更容易维护和重用)。
-
如果使用得当,全球variables污染可以被完全抑制。
老实说,一旦你的脑袋里点了一个概念,你就永远不会回到以前的样子。
PS:jQuery从1.7版本开始注册为AMD模块。
有关AMDS的更多信息:
- https://github.com/cujojs/curl
- http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
- http://requirejs.org/
- http://www.bennadel.com/blog/2275-Using-RequireJS-For-Asynchronous-Script-Loading-And-JavaScript-Dependency-Management.htm
- https://github.com/Integralist/Blog-Posts/blob/master/2012-01-04-Beginners-guide-to-AMD-and-RequireJS.md
对于JavaScript代码,我发现以下链接从基督教海尔曼不可或缺
- 模块模式
- configuration脚本
我也非常喜欢Peter Michaux 在这里描述的方法
对于jQuery,我衷心推荐阅读创作指南,我发现本教程中的jQuery 插件模式非常好
为了保持我的事件在控制我使用发布/订阅机制
jQuery.subscribe = function( eventName, obj, method ){ $(window).bind( eventName, function() { obj[method].apply( obj, Array.prototype.slice.call( arguments, 1 ) ); }); return jQuery; } jQuery.publish = function(eventName){ $( window ).trigger( eventName, Array.prototype.slice.call( arguments, 1 ) ); return jQuery; }
这是一个使用的例子
// a couple of objects to work with var myObj = { method1: function( arg ) { alert( 'myObj::method1 says: '+arg ); }, method2: function( arg1, arg2 ) { alert( arg1 ); //republish $.publish( 'anEventNameIMadeUp', arg2 ); } } var myOtherObj = { say: function(arg){ alert('myOtherObj::say says: ' + arg); } } // you can then have all your event connections in one place //myObj::method2 is now listening for the 'start' event $.subscribe( 'start', myObj, 'method2' ); //myOtherObj::say is now listening for the 'another' event $.subscribe( 'anotherEvent', myOtherObj, 'say' ); //myObj::method1 is now listening for the 'anEventNameIMadeUp' event $.subscribe( 'anEventNameIMadeUp', myObj, 'method1' ); //so is myOtherObj::say $.subscribe( 'anEventNameIMadeUp', myOtherObj, 'say' ); // ok, trigger some events (this could happen anywhere) $.publish( 'start', 'message1', 'message2' ); $.publish( 'anotherEvent', 'another message' );
我绝对推荐阅读对象文字模式,除了模块模式; 这里有一个很好的写法:
(function($, window, slice) { $.subscribe = function(eventName, obj, method) { $(window).bind(eventName, function() { obj[method].apply(obj, slice.call(arguments, 1)); }); return $; }; $.publish = function(eventName) { $(window).trigger(eventName, slice.call(arguments, 1)); return jQuery; }; })(jQuery, window, Array.prototype.slice);
为了增加现有的答案,这里有一个很好的post ,涵盖了构build在模块模式上的更高级的技术。
一旦你的Javascript代码达到一定的大小,你将不可避免地想要重构它分成多个文件/模块/子模块。 如果您不确定如何使用模块模式来完成此操作,则必须阅读本文。
我的js文件通常遵循与此类似的命名约定:
- xxx.utility.js
- mypage.events.js
- xxx.common.js
- / lib目录/
- / OS-DoNotDistribute / LIB /
哪里
- 'mypage'是html,aspx,php等文件的名称。
- 'xxx'是这个概念。 (即orders.common.js)
- 'utility'表示这是一个可重用的库脚本(即ajax.utility.js,controlfader.utility.js)
- “普通”是这个应用程序的可重用function,但不能在其他项目中重复使用
- 'lib'是任何外部或库脚本的子目录
- 'OS-DoNotDistribute'是一个子目录,以确保如果应用程序被出售,则不会分发操作系统授权代码。
另外,对于Ajax,我有一个特殊的callback函数命名约定,所以很容易告诉它们是什么。
我不确定这是否接近你正在寻找的东西,但我希望它有帮助。
我真的很喜欢这些文章:
http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html
http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/
他们帮助我了解telerik如何为asp.net mvc创build扩展。
我喜欢AMD的想法(见尼克斯的答案 )。
但我通常编译所有我的JS文件到一个JS文件。 在这种情况下,不需要asynchronous部分。 于是我写了一个“Infile Module Loader”。
这里是: https : //codereview.stackexchange.com/questions/14530/a-little-infile-amd
我们可以在我们的javascript-jquery应用程序中使用mvc模式。 (Backbone.js,knockout.js vs ….)是我们可以用于这个目标的成熟的库。