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

来源:互联网 发布:数据资产管理平台 开源 编辑:程序博客网 时间:2024/05/22 03:24

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

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

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.事件统一管理

  1. ##### 将事件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',        };            };
  1. ##### 将事件要触发的函数写进原型中。

(注意此时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();            }        },    }
  1. ##### 我们会使用事件代理的方式对这些事件进行循环绑定。

在原型中书写一个扫描事件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]);                }            }        },          }
  1. ##### 在原型中写入以下函数,优化我们的逻辑。
  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) { //扫描事件地图,绑定或者解绑        },          }
  1. ##### 在构造函数内调用初始化函数。
    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);
0 0
原创粉丝点击