zoukankan      html  css  js  c++  java
  • 如何编写高质量代码

    对于开发人员来说,编写高质量的代码是有很重要的意义的,特别是在团队协作里。本篇博文从前端开发的角度,总结出编写高质量前端代码的一些经验。前端开发涉及的主要语言包括html,css,js等。这里主要针对JS来介绍。

    编码思维

    1. 逻辑思维

    当接到某个任务的时候,不要急于开始动手,而是先静下心来思考,理清这个任务要实现的功能,这个功能用在什么场景下,将来是否会复用,如果将来会变化,可能会怎样变化。要怎么设计利于功能的扩展和优化,可能会出现哪些问题,如何规避问题。这些都是在前期动笔前需要思考清楚的,不然到后面开发的时候可能会不停的修改,最终效率越来越低。一个功能有着良好的运行逻辑,才不会容易出错。当然如果时间不允许,或是只上一次就废弃的功能,此时效率可能会优先考虑。

    通常专业的设计师,在设计网页的时候会使页面保持相同的风格,相似的模块同质性很高,这些在我们开发的时候,对复用性较高的代码定义成公共的模块或组件。甚至我们在接到设计稿的时候,对于差异较大但是功能类似的页面提出疑问,提醒视觉保持统一。

    有良好的逻辑思维能力和丰富的工作经验能使我们想的更深更远。对写代码保持强烈的热情跟好奇心,多看多读,有些代码晦涩难懂,比如复杂的算法或是新的概念,没关系,第一次看了了解,第二次看了就熟悉,第三次可能就精通了,坚持学习和吸收新的知识,有助于我们更好的了解需要开发的功能,磨练自己的逻辑思维,增加解决问题的办法。

    2. 优化思维

    对于自己写过的代码持怀疑态度,追求完美的代码。何为完美,每个人的标准不一样。对于自己写过的代码,写完后想想整个的流程,是否还有值得优化的地方。尽量用最简洁的代码来实现,比如用三元运算符代替if语句,重复的代码提取成方法,重用的功能写成一个组件等等。对于写的不好的代码要有重构的勇气和信心。

    在开发的过程中,还时时需要考虑页面的性能,选择性能最好的解决方案。比如JS少用全局变量,用完后及时销毁,合理使用闭包,避免频繁操作DOM节点,大量的计算等,HTML代码的SEO优化,样式的合理组织等,开发完后通过firebug或chrome自带的调试工具查看页面加载的速度,资源大小等,然后有针对性的优化。

    3. 设计思维

    作为一名前端开发,懂点设计的基础是很有必要的。前端的设计是指一个画面或元素,如何在不同的浏览器,不同的设备上被创建,显示,或删除。我们除了直接跟设计师打交道外,还直接面向用户,做好响应式的设计与开发,从用户的角度出发,客观的评价设计稿所传达的信息,是否体验最优,就是我们前端的设计思维。设计的思维,会直接影响我们写代码的结构。

    JS代码规范

    1.前端代码的组织结构和文件的命名

    代码文件组织结构。前端文件主要包含HTML、CSS、JS等,对于文件组织,既要考虑结构清晰一目了然还要考虑代码的复用。基于这样的原则,惯用的做法是同类文件放在一起,并按模块划分文件结构。比如页面中公用的组件放到外部公共的components文件夹里,页面特有的组件则放到该模块对应的JS文件夹里,每个组件对应有html,js,css等内容。

    代码文件的命名。名称需要表明文件对应的模块内容和文件的格式等。使用语义化的名字,避免使用数字来命名,比如a1.html,a2.html等。

    2.命名规范

    2.1变量

    使用合理易于理解的英文变量名称,变量命名的风格统一,比如都用驼峰命名法,局部变量名尽量简短。NEJ里的规范,局部变用接口内局部变量或者传递的参数用_来量表示,如_type,_index等。对象外可访问的接口或者属性,用_$开头,_$$表示类对象等。

    声明变量必须加上 var 关键字.当你没有写 var, 变量就会暴露在全局上下文中, 这样很可能会和现有变量冲突。变量需先声明后使用,防止变量提升。

    另外常量名字都用大写。

    2.2方法

    JS面向对象开发中公有接口命名首字母为大写,私有接口命名首字母小写。事件的命名用动词+名词+动词的方式,方法名具有语义化,尽量完整。如:onExchange,doExchange,cbExchange等。逻辑操作符 || 和 && 可被用来返回布尔值,简化代码。

    3.代码注释

    代码加上合理的注释,提高可读性。例如对于某个功能的简介,或者变量的特殊含义和用处。每个JS文件头部说明下作者,日期,文件介绍等。

    /**
    * KJ-13989 组团买好货
    * author AAA
    * 2015-12-09 
    */
    
    /**
     * 接口函数的说明
     * 参数说明
     */
    /**
      * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
      *
      * @param {function} func    传入函数
      * @param {number}  wait    表示时间窗口的间隔
      * @param {boolean} immediate  设置为ture时,调用触发于开始边界而不是结束边界
      * @return {function}       返回客户调用函数
      */

    当你写注释时一定要注意:不要写你的代码都干了些什么,而要写你的代码为什么要这么写,背后的考量是什么。对于文件的修改,也可以在注释里加上相关的任务号。

    4.语句结束时添加分号

    记得语句结束时使用分号。如果仅依靠语句间的隐式分隔, 有时会很麻烦。而且添加分号也利于代码的理解。

    5.不要在块内声明一个函数,使用函数表达式来定义函数

    不要写成:

    if (x) {
      function foo() {}
    }

    虽然很多 JS 引擎都支持块内声明函数, 但它不属于 ECMAScript 规范 (见 ECMA-262, 第13和14条)。 各个浏览器的实现相互不兼容, 有些也与未来 ECMAScript 草案相违背。ECMAScript 只允许在脚本的根语句或函数中声明函数。 如果确实需要在块中定义函数, 建议使用函数表达式来初始化变量:

    if (x) {
      var foo = function() {}
    }

    6.避免定义全局变量或函数

    函数可以采用匿名函数包裹的方法实现封装,如

    (function(){
        //do some thing
    })()

    全局变量可以通过定义全局对象变量来存储,像在ftl页面的JS中定义ftl值的时候,可以统一写成:

    var configInfos ={
            remindType:${remindType!2},
            totalPoint:${pointTotalCount!0},
            isSigned:"${isSigned?string('yes','no')}"
        }

    而后通过configInfos.remindType获取到remindType值。这样可以减少全局变量的个数,避免变量冲突。

    7.使用单引号定义字符串。

    ftl文件中用双引号,JS中用单引号。

    8.使用简化的编码方式。

    如对象和数组的声明,三元操作符等。

    var a = [],obj={};

    9.避免使用with语句。

    该语句在设计上就有缺陷,在ES5和ES6上也存在潜在兼容问题。对性能也有很大影响。

    10.避免使用eval。

    存在潜在安全问题,在需要使用eval的场景中应当尽量使用其它方法代替。

    11.事件处理和业务逻辑分离,数据和代码逻辑分离。

    现在使用的RegularJs框架正是实现了数据与代码逻辑的分离。

    12.结构样式与逻辑分离

    CSS样式分离,将多个样式放置在class中后控制class的增删,通过挂靠样式名来改变样式。避免在JS中对元素操作大量的style来改变样式。

    _e._$addClassName(this.__passWord,'u-ipt-login-active');

    13.合理定义交互元素的样式名

    在JS中,可以通过获取元素的className,id,或元素名来操作DOM节点。如果是页面上固定的节点,则可以通过给元素挂靠'ztag','j-flag'等样式名。这些名字不需要带任何样式。避免用大量的id来获取元素。如果是通过判断来显示的元素,则可以通过ID来获取。

    pro.__getNodes = function(){
            var _node = _e._$getByClassName(document.body,'ztag'),i=0;
            this.__aboutWrap = _node[i++];
            this.__goodsDescWrap = _node[i++];
            this.__fixedBtn = _node[i++];
            this.__payBtn = _node[i++];
        };

    14.代码格式化

    15.理解 JavaScript 的定义域和定义域提升,提前声明变量

    在 JavaScript 中变量和方法定义会自动提升到执行之前。JavaScript 只有 function 级的定义域,而无其他很多编程语言中的块定义域,所以使得你在某一function 内的某语句和循环体中定义了一个变量,此变量可作用于整个 function 内,而不仅仅是在此语句或循环体中,因为它们的声明被 JavaScript 自动提升了。所以一般在函数开头先声明好变量。避免变量在定义前被使用,导致报错。

    16.合理使用AJAX技术

    明确AJAX技术的使用场景,在AJAX过程中做好用户的交互,如禁用按钮避免重复触发、显示加载进度条等。

    17.内存回收

    全局对象或对象的属性使用完后,将值设为null或undefined,或者某个实例化的组件,使用后及时解除引用(recycle或destroy方法),解除已经不需要的事件监听(delEvent),不要在函数内返回外部不需要的对象等。这些操作利于浏览器的回收程序执行时能回收其占用的内存。

    18.使用高性能的变量或属性值的读取方式

    在使用变量和属性时,如果需要多次调用,则定义成局部变量再使用。最简单的例如for循环中,可以将变量或属性缓存起来:

    for(var i=0,len=number.length;i<len;i++){}

    变量涉及作用域链查找的过程,属性涉及原型链查找的过程,定义成局部变量可以节约查找的时间。

    19.高效的DOM操作

    DOM操作对性能最大的影响是因为它导致了浏览器的重排和重绘。

    使用文档片段:创建一个文档片段(documentFragment),并在此片段上进行DOM操作,操作完成后将它附加在页面中,这样重排和重绘的操作就只有附加了。

    通过设置DOM元素额的display样式为none来隐藏元素:通过隐藏DOM达到在页面中移除元素的效果,这样重排和重绘的操作就只有隐藏和显示了。

    克隆DOM元素到内存中:将元素克隆一份然后在内存中操作DOM,操作完之后替换,这样重排和重绘的操作就只有替换了。当元素中有事件绑定时,cloneNode会把事件移除掉,不适合用这种方法来操作。

    设置具有动画效果的DOM元素的position为fixed或absolute:使元素脱离页面布局流,从而避免页面频繁的重排。

    谨慎取得DOM元素的布局信息(offsetHeight等):如果需要重复使用这些信息可以先缓存起来。

    使用事件委托来绑定事件:利用事件冒泡机制,只在父元素上绑定事件,然后在事件处理函数中根据传入的参数判断事件的源元素,然后针对不同的源元素做不同的处理。这样避免了给多个子元素绑定事件。

    20.增加容错处理

    例如给变量或属性设置默认值,对某段代码使用try,catch操作。

    21.代码注意安全性

    常见的Web前端攻击方式有XSS Cross Site Scripting 跨站点脚本攻击,CSRF Cross Site Request Forgery 跨站请求伪造,界面操作劫持等。我们需要注意的是不轻信任何用户输入的内容,针对用户输入的内容进行HTML编码、JavaScript编码、CSS编码、URL编码等。对用户表单提交的数据做完整的验证。

    22.移动端开发注意点

    使用流式布局。使用合适的图片显示兼容方案。使用移动平台特有事件处理如手势操作。增加链接按钮的可操作区域,如安卓开发规范中保证这些控件的高度至少有48px间隔至少有32px等。

    23.代码检查,code review

    24.ftl里代码优化

    ftl里避免在JS中填充大量的数据,尤其是像列表数据,不利于优化。如果确实需要,在JS获得数据后删除该节点。

    其他注意点

    1.提前设计

    提前规划设计好,从全局角度规划代码的结构。保证代码精简,写完某个功能后重新思考下整个流程,是否可以优化,方向有没有写错。

    我记得刚开始写代码的时候,某个功能写到某一步的时候,发现写不下去了,这个时候只能重新换个思路,推倒之前的代码重新写。这就是没有提前规划好思路,急于下笔,导致浪费了很多时间。

    2.前端代码重构注意事项

    重构前一定要预估风险,如果没有足够的自动化测试,最好是先完善自动化测试代码。

    重构的目的和范围要明确,切忌盲目修改,前端代码的重构目的主要是提高代码的可维护性、可读性和性能。

    最好是先易后难,循序渐进。首先修改诸如命名、格式等不涉及具体逻辑的内容,然后考虑模块化和性能提升等具体逻辑相关的内容。

    重构过程中要持续测试,在多个浏览器中测试,确保重构一部分功能正确,切忌在大量重构后再进行测试,因为大量重构后基本很难记得重构的逻辑,也就有可能遗漏部分测试用例。

    如果是提升性能,要事先检测网站的整体性能并量化,找出性能瓶颈,重构过程中要持续监控性能,并对比性能提升的效果。

    3.快速编写页面

    拿到设计稿后,规划好结构,先写完html代码,最后再补充完整的样式,这样效率最高。边写边调是很浪费时间的。

    参考文章:

    http://itwap.net/ArticleContent.aspx?id=35

    http://www.css88.com/archives/5366

  • 相关阅读:
    hdu 5101 Select
    hdu 5100 Chessboard
    cf B. I.O.U.
    cf C. Inna and Dima
    cf B. Inna and Nine
    cf C. Counting Kangaroos is Fun
    Radar Installation 贪心
    spfa模板
    Sequence
    棋盘问题
  • 原文地址:https://www.cnblogs.com/zourong/p/5116788.html
Copyright © 2011-2022 走看看