《编写优雅的前端业务代码》听后感

这场知乎live主要拿了一份现实工作中的业务代码进行一步步地优化分析。每个人的收获都是不一样的。我就以我的水平去总结一下这场live,也说说我的收获。

原来的代码一共300行不到的js,用jquery写的。整个代码结构,就是前面定义少许变量,然后一堆函数,一堆事件的绑定,中间夹杂着几个函数的调用,算是初始化的功能吧。对这份代码的整体感受,代码格式整洁,有些注释,太多DOM操作,太多样式的计算看得有点眼花缭乱。

对于我这种小白水平的来说,如果要我去优化。我会做的不多,最多就是把那些函数的调用放在一块,省得找来找去的。可能会调换一下代码的顺序,更好读一些。一个函数如果业务太多,拆分成多个子函数来实现。提取一些复用的函数和变量。

然后,我们看下大神是怎么做的。

第一次优化

这一次在结构上是比较大的修改,算是一次大重构。首先用经典的立即执行函数写法把所有代码包起来( 主要作用应该是避免污染全局变量 ),一般jquery的插件都可以看到。而原始代码用的仅仅是$(function(){ //some code }),主要是为了保证在dom加载完毕之后才执行代码。

然后在代码结构上,将代码写成模块的形式。定义了一个构造函数(来模拟类), 函数内部做了一些初始化操作的事情,然后在把那些方法定义在它的原型对象(prototype)上,顺便把这个类暴露给全局变量,然后在dom加载完毕之后进行实例化。简化的框架如下:

// 立即执行函数
(function($, global, doc){
    var app = function(options){
       // 一些变量的初始化
       //  执行某些函数,进行初始化
        init(); 
    };

    app.eles = {};  //存了一些元素的map,用静态变量的形式。我觉得写在上面匿名函数内部this.eles也是一样的吧!?

    app.prototype = {
        constructor: app,  // 修改构造器的指向
       // 前面加_表示内部私有函数,一种约定习惯吧
        _foo: function(){

        },
        init: function(){

        }
        // ...
        // 以及 所有的函数方法 
    }

    // 将这个模块暴露给全局变量
    window.app = app;

    // dom加载完毕之后,实例化一次
    $( function() {
        new app();
    })

})(jQuery, window, document, undefined)

再细节地来说,整个代码加入了生命周期的概念。生命周期的概念我听过,比如一些框架都有自己的一套生命周期,但我不怎么熟悉。对业务代码的生命周期的概念更加模糊,其实也有看过或者接触过。听完这场live之后,我理解的业务代码的生命周期,就是初始化过程中,初始化一些组件,绑定一些事件啊,然后在最后销毁这个模块的时候,将这些组件销毁,将事件解绑。我觉得主要的目的就是释放内存吧。是不是理解的对不对,或者理解地比较狭窄?

然后它还做了个小细节的优化,就是所有事件绑定的都整理到一块,写在一个eventsMap里面,用一个函数将元素和事件绑定在一块。

app.prototype = {
    constructor: app,  // 修改构造器的指向
   // 前面加_表示内部私有函数,一种约定习惯吧
    _foo: function(){

    },
    init: function(){
        // 初始化操作
        this.initWidgets();
        this.bindEvents();
    },
    initWidgets: function(){
        // 初始化组件
    },
    destroyWidgets: function(){
        // 销毁组件
    },
    bindEvents: function(){
        // 绑定事件
    },
    unbindEvents: function(){
       // 解绑事件
    }
    destroy: function(){
        // 整个模块的销毁
        this.unbindEvents();
        this.destroyWidgets(); 
    }
    // ...
    // 以及 所有的函数方法 
}

到此,整个代码的结构都清晰了很多。

第二次优化

这次主要是细节上的优化,把常用的变量和dom元素提取出来集中管理,函数内部的一些变量也提取在函数内部的最前面,以便于复用。一个注意点就是dom的元素可以保存为一个变量,这样有利于代码压缩。因为如果你是$(‘myContent’),里面的’myContent’是无法被压缩的。还有,一个函数如果太长了,将内部部分代码抽取出来变成一个新的函数,这样可读性强一些。这些算是比较常规的优化。

第三次优化

提取了公共的基础函数库,封装在util对象中。一些if语句用三元表达式来代替,switch语句改成更加合理的方式。

第四次优化

这次优化也是一次大重构。它结合了模块化,类和继承等用ES6语法重构了一次。本来是一个300行不到的js文件,现在拆成了7个加起来500多行的js文件。

这里写图片描述

代码看得懂,可能自己写不出来,ES6还没好好地看好一遍,对类和继承理解也还没那么深刻。我觉得这里比较巧妙的是,多级继承的写法。在定义的时候,将父类作为函数变量,使得最后myApp的类继承自一个高阶函数的样子。我是第一次见过这样的写法。抽出来这些代码的关键部分:

// myApp.js
import  ...  from ...
....

class myApp extends drag(resize(base(config))){
    constructor( options ){

    }
    ...
}

export default myApp

// resize.js

import ... from ...

let resize = ( superclass ) => class extends superclass {
    constructor(){
    }
    ...
}

export default resize

总之,这次改造非常高大上,需要很好地掌握模块化,类,继承,以及ES6的语法糖。

这次live,从一个很一般的js业务代码一步一步地重构,的确挺有收获的。

最后大神对这次live进行了总结。我用我的话来说一下那些我理解的点:

  • 合理的选择器:无意义的样式,以 “j-“为前缀
  • 选择器的统一管理
  • 事件绑定的统一管理
  • 生命周期的概念
  • 方法的复用
  • 模块化

转载请注明出处:http://blog.csdn.net/fen747042796 野草园
欢迎关注我的知乎:野蛮的小小芬

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值