danny.chiu 发表于 2013-1-24 06:41:25

JS架构探讨-精彩討論进行中...

此前做过一个坦克大战小游戏,感谢大家热情回复,但从此中也发现前台开发人员水平参差,而且从接触到的同行可以看出,这方面大家的理解差距较大。

    JS前景很好,2014年HTML5标准更新之后,在很长的时间内,她都会越来越流行,特别是在游戏横行,移动设备更新快,很多人又不愿意用各种软件把手机弄得半死不活的今天,JS在移动设备上可能可能首先打败flash,成为前端的一哥。

    为什么要写此文?不可否认JS越来越流行,因为她灵活,什么样的水平都可以写出能实现功能的代码;这也突显出一个尖锐的问题:代码规范化。至于架构的重要性,我想不用多说,无非是规范代码、提高重用性、易扩展易维护。百度、新浪、豆瓣等都有自己的架构,今天在下分享一个DEMO,希望抛砖引玉,懂行的不要保留,分享是金;顺便把新浪架构PPT分享给大家。

    个人对架构的理解,无非是分层和模块化,以下代码主要基于此理解。使用jQuery作为底层,模块为中层,功能为上层、模块的组合。我们的目的是用此框架,我们可以把注意力集中在模块开发上,以实现易扩展、易重用、规范化的目标。

    待完善的地方有很多,比如针对每个页面独立一个配置文件(例如JSON),服务器端把此页面用到的JS合并压缩,以减少请求数,等,期待大家提出更多更好的建议。

http://dl.iteye.com/upload/attachment/483678/546ffd07-775c-36ee-91cd-085c300f1209.png
核心实现:constructor/js/aispeech.jsvar AIS = (function() {var ONE_PROP = 'test'; // 私有属性和私有方法,只供框架内部使用return {create: function(obj, supr) { // 创建类或子类var sb = obj.initialize, sp;delete obj.initialize;if (!supr || typeof supr === 'object') {sb.prototype = obj;} else {sp = function() {};sp.prototype = supr.prototype;sb.prototype = new sp();sb.supr = sp.prototype;$.extend(sb.prototype, obj);}sb.prototype.constructor = sb;return sb;},getScript: function(url, cb) { // 引入js文件$.getScript(url, cb);},modual: {}, // 注册模块及其路径namespace: function(ns, cb) { // 命名空间var nsArr = ns.split('.'), o;o = window] = window] || {};$.each(nsArr.slice(1), function(i, n) {o = o = o || {};});AIS.modual.ns = ns;if (cb && typeof cb === 'function') cb.call(o);},importMD: function(modual, cb) { // 导入模块,根据模块名cb = cb || function() {};if (AIS.modual.ns) {cb.call(eval(AIS.modual.ns));} else {AIS.getScript(AIS.modual.url, function() {cb.call(eval(AIS.modual.ns));});}},util: { // 工具集isEmptyObject: function(obj) {for (var prop in obj) {return false;}return true;},toArray: function(arrLike) {return Array.prototype.slice(arrLike);},// browsers..isIE: function() {return !-;}}}})();
使用方法:var A = AIS.create({initialize: function(name) { // 每个类都必须声明的构造器方法this.name = name;},hello: function() {alert('hello: '+ this.name);}});var a = new A('danny');a.hello();var B = AIS.create({// B继承自Ainitialize: function(name, age) {B.supr.constructor.call(this, name);this.age = age;},world: function() {alert('world: '+ this.age);}}, A);
一个用户登陆和切换用户的DEMO:
constructor/ais.modual.jsAIS.modual = {'login': {'url': 'js/login/login.js'},'switcher': {'url': 'js/login/switch.js'}}
constructor/js/login/login.jsAIS.namespace('com.ais.aid201105.login', function() {//var PrivateClass = AIS.create({...}); 可以创建包内私有的类this.LoginForm = AIS.create({ // public classinitialize: function(pid) {this.parentId = pid;this.initForm();this.submit();},initForm: function() {var $f = $('<form></form>');$f.append('<fieldset style="width: 250px;"></fieldset>').find('fieldset').append('<legend>Login Form</legend>').append('<label class="username">name: </label> <input type="text" id="username" /><br />').append('<label class="password">password: </label> <input type="password" id="password" /><br />').append('<label class="gender">gender: </label> <select id="gender"><option>male</option><option>female</option></select><br />').append('<input type="button" id="submit" value="submit" /> <input type="reset" value="reset" />');$('#' + this.parentId).html($f).show('slow').find('#username').focus();$('.username, .password, .gender').css({'display': 'inline-block','width': '70px','text-align': 'right'});},submit: function() {var that = this;$('#submit').click(function() {//alert('name: ' + $('#username').val() + '\npassword: ' + $('#password').val()); // submit check$('#' + that.parentId).hide();$('#welcome').find('span').text($('#username').val()).end().show();});}});});
切换用户引用登陆
constructor/js/login/switch.jsAIS.namespace('com.ais.aid201105.switcher', function() {this.Switch = AIS.create({initialize: function(sid, lid) {this.switchId = sid;this.lid = lid;this.attachEvent();},attachEvent: function() {var that = this;$('#switch').click(function() {AIS.importMD('login', function() {new this.LoginForm(that.lid);});$('#welcome').hide();});}});});

constructor/js/index.js$(function() { // indexAIS.importMD('login', function() {new this.LoginForm('login_md');});AIS.importMD('switcher', function() {new this.Switch('switch', 'login_md');});})

constructor/index.html<!DOCTYPE HTML><html><head><script type="text/javascript" src="js/jquery-1.6.min.js"></script><script type="text/javascript" src="js/aispeech.js"></script><script type="text/javascript" src="js/ais.modual.js"></script><script type="text/javascript" src="js/index.js"></script></head><body><div id="welcome" style="display: none;">欢迎<b><span></span></b> | <a href="#" id="switch">切换用户</a></div><div id="login_md"></div></body></html>
页: [1]
查看完整版本: JS架构探讨-精彩討論进行中...