admin管理员组

文章数量:1794759

代码重构(编写优雅的前端代码)

代码重构(编写优雅的前端代码)

代码重构(编写优雅的前端代码)

    • 代码重构编写优雅的前端代码
      • 自执行函数严格模式
      • 构造函数与原型
      • 选择器统一管理
      • 事件统一管理
      • 添加属性和方法
      • 抽离工具类对象
      • 执行构造函数
      • 最终结构

1.自执行函数,严格模式

将当前的模块对象写在一个自执行函数内。

需要使用ES5的严格模式。

该模块需要用到的全局变量需要用入参的方式传入自执行函数,供函数内部使用。

(function (global, $, doc, lsObj, zhugeSwitch, zhuge) { 'use strict'; /* 这里是代码 */ })(this, this.jQuery, document, lsObj, zhugeSwitch, zhuge); 2.构造函数与原型

为当前模块对象创建一个构造函数,和他的原型。

我们将构造函数作为模块的入口函数。入口函数里通常会执行初始化变量、绑定事件等等。

(function (global, $, doc, lsObj, zhugeSwitch, zhuge) { 'use strict'; var something = function(){ }; something.prototype = { constructor: something, } })(this, this.jQuery, document, lsObj, zhugeSwitch, zhuge); 3.选择器统一管理

将选择器对象写在类属性中。

将初始化选择器的函数写在原型中,在构造函数内调用。

var something = function(){ this.initializeElements(); }; something.Eles = { name: '.name', password: '.password', }; something.prototype = { initializeElements: function () { var eles = loginClass.Eles; for (var name in eles) { if (eles.hasOwnProperty(name)) { this[name] = $(eles[name]); } } } } 4.事件统一管理
  • ##### 将事件Map统一写在构造内。
  • var something = function(){ this.eventsMap = { 'focus .name input': 'nameFocus', 'blur .name input': 'nameBlur', 'focus .password input': 'pswdFocus', 'blur .password input': 'pswdBlur', 'click .btn': 'login', }; };
  • ##### 将事件要触发的函数写进原型中。
  • (注意此时this的指向)

    something.prototype = { login: function () { var p = this.passwordInput; var n = this.nameInput; var pt = this.pTip; var nt = this.nTip; this.nameVal = n.val().trim(); this.passwordVal = MD5(p.val().trim()); var nameVal = this.nameVal; var passwordVal = this.nameVal; var phoneReg = /^1\\d{10}$/; if (nameVal == "" || nameVal == null) { nt.text('手机号码不能为空'); p.val('') } else if (!phoneReg.test(nameVal)) { nt.text('您输入的手机号码不正确'); } else if (passwordVal == '' || passwordVal == null) { nt.text(''); pt.text('密码不能为空'); } else { nt.text(''); pt.text(''); this._requestIfTelregisted(); } }, }
  • ##### 我们会使用事件代理的方式对这些事件进行循环绑定。
  • 在原型中书写一个扫描事件Map的函数。

    something.prototype = { _scanEventsMap: function (maps, isOn) { var delegateEventSplitter = /^(\\S+)\\s*(.*)$/; var type = isOn ? 'on' : 'off'; for (var keys in maps) { if (maps.hasOwnProperty(keys)) { if (typeof maps[keys] === 'string') { maps[keys] = this[maps[keys]].bind(this); //改变this的指向 } var matchs = keys.match(delegateEventSplitter); $('body')[type](matchs[1], matchs[2], maps[keys]); } } }, }
  • ##### 在原型中写入以下函数,优化我们的逻辑。
  • something.prototype = { initialization: function () { //初始化 this.bindEvent(); }, bindEvent: function () { //绑定事件 this.initializeOrdinaryEvent(this.eventsMap); }, unbindEvent: function () { //解绑事件 this.uninitializeOrdinaryEvent(this.eventsMap); }, initializeOrdinaryEvent: function (maps) { //绑定普通事件 this._scanEventsMap(maps, true); }, uninitializeOrdinaryEvent: function (maps) { //解绑普通事件 this._scanEventsMap(maps); }, _scanEventsMap: function (maps, isOn) { //扫描事件地图,绑定或者解绑 }, }
  • ##### 在构造函数内调用初始化函数。
  • var something = function(){ this.initialization(); }; 5.添加属性和方法

    当前模块对象会有一些初始化参数,可以理解为我们自己定义的全局变量。我们将这些参数写进构造函数中。

    var something = function(){ this.passwordVal = null; this.nameVal = null; };

    将其他用到的函数写入原型中。

    something.prototype = { _requestIfTelregisted: function () { // 验证手机号是否注册接口 var _data = { "registNum": this.nameVal }; var nt = this.nTip; var that = this; $.ajax({ type: "GET", url: "/cloudlink-core-framework/login/isExist", contentType: "application/json", data: _data, dataType: "json", success: function (data, status) { var res = data.rows.isExist; if (res == 0) { nt.text('账号未注册'); utils.zhugeTrackForFailed(that.nameVal,'账号未注册'); return false; } else { that._requestData(); return true; } } }); }, } 6.抽离工具类(对象)

    例如:

    var utils = { hide:function(ele){ //元素的显隐 $(ele).addClass('hidden'); }, show:function(ele){ $(ele).removeClass('hidden'); }, zhugeTrackForFailed: function (tel, sRsn) { //诸葛埋点 if (zhugeSwitch == 1) { zhuge.track('登陆失败', { '手机号': tel, '原因': sRsn }); } }, }; 7.执行构造函数

    可以选择是否把类或new出的对象暴露出去。

    //global.something = something; 选择是或否暴露 $(function() { global.somethingObj = new something(); //暴露出对象,供其他使用 //new something(); 直接执行 }); 8.最终结构 (function (global, $, doc, lsObj, zhugeSwitch, zhuge) { 'use strict'; var something = function(){ this.eventsMap = { 'focus .name input': 'nameFocus', }; this.initializeElements(); this.initialization(); }; something.Eles = { password: '.password', }; var utils = { zhugeTrackForFailed: function(tel, sRsn) { if (zhugeSwitch == 1) { zhuge.track('登陆失败', { '手机号': tel, '原因': sRsn }); } }, }; something.prototype = { constructor: something, initialization: function() { this.bindEvent(); }, initializeElements: function() { var eles = loginClass.Eles; for (var name in eles) { if (eles.hasOwnProperty(name)) { this[name] = $(eles[name]); } } }, bindEvent: function() { this.initializeOrdinaryEvent(this.eventsMap); }, unbindEvent: function() { this.uninitializeOrdinaryEvent(this.eventsMap); }, initializeOrdinaryEvent: function(maps) { this._scanEventsMap(maps, true); }, uninitializeOrdinaryEvent: function(maps) { this._scanEventsMap(maps); }, _scanEventsMap: function(maps, isOn) { var delegateEventSplitter = /^(\\S+)\\s*(.*)$/; var type = isOn ? 'on' : 'off'; for (var keys in maps) { if (maps.hasOwnProperty(keys)) { if (typeof maps[keys] === 'string') { maps[keys] = this[maps[keys]].bind(this); } var matchs = keys.match(delegateEventSplitter); $('body')[type](matchs[1], matchs[2], maps[keys]); } } }, destroy: function() { this.unbindEvent(); } } //global.something = something; 选择是或否暴露 $(function() { global.somethingObj = new something(); //暴露出对象,供其他使用 //new something(); 直接执行 }); })(this, this.jQuery, document, lsObj, zhugeSwitch, zhuge);

    本文标签: 代码重构优雅