前端代码质量的思考与实践编写可读代码对于靠代码为生的程序员来说是一件极其重要的事情。从某种角度来说,代码最重要的功能是能够被阅读,其次才是能够被正确执行。一段没有正确执行的代码可能会拖延几天的项目,但它造成的危害只是暂时的和轻微的,毕竟这段代码无法通过测试,影响最终的产品;代码难读,造成的危害是深远而广泛的:这种代码会增加产品后续迭代和维护的成本,影响产品的稳定性,破坏团队的团结,除非我们花费数倍于编写这段代码的时间和精力来消除它对项目的负面影响。JavaScript是一种动态的弱类型语言,使用起来比较简单随意。在IE6这个刀耕火种的时代,轻松随意的习惯确实不是什么大问题,反而可以节省时间,提高工作速度。然而,随着当前前端工程技术的飞速发展和前端项目规模的不断扩大,以往轻松随意的编码习惯已经成为项目推进的一大障碍。分享和鼓励任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员编写人类可以理解的代码。——MartinFowler好的代码就是它自己最好的文档。当你要添加评论时,问问自己,“我怎样才能改进代码,这样就不需要这个评论了?”——SteveMcConnell程序必须编写供人们阅读,并且只是偶然地供机器执行。HaroldAbelsonHTML实践使用语义标签实现清晰、简洁的层次结构在嵌套结构中尽可能少使用无意义的标签,比如div和span,语义不明显的,可以使用p或div,p标签是首选。在语义不能用标签表达的情况下,在CSS实践中添加适当的注释引入sass或其他css预处理器命名可以参考BEM命名法和dash命名法。根节点使用id选择器,其他使用class选择器,children替换后代。css属性的写法使用约定的类命名顺序破折号分隔不要超过4层,如果超过0,尽量避免使用float和position,使用flex布局和grid布局。如果只能这样写直接css,也可以参考上面的思路。如果不能直接导入sass,可以使用IDE或者terminal手动导入。练习变量 翻译javascript和jQuery变量命名是编写可读代码的基础。一个变量只有被赋予一个合适的名字,才能表达它在环境中的意义。 命名必须传递足够的信息,getData这样的函数名不能提供足够的信息,读者根本猜不到这个函数会做什么。而fetchUserInfoAsync可能会好很多,读者至少会猜到这个函数会远程获取用户信息;并且因为它有一个Async后缀,读者甚至可以猜到这个函数会返回一个Promise对象。命名依据。用名词命名对象,用动词命名函数,用复数表示集合。您还可以添加List或Map后缀来显式表达它们,使代码接近自然语言。建议变量命名使用小驼峰命名,类命名使用大驼峰命名。命名约定。始终遵循一定的规则来命名变量和函数,因此您不必担心变量污染和知道名称。例如:fetch或async代表异步,get代表获取,set代表设置,is,has,可以代表一个布尔值,handle代表普通函数等等。命名上下文。变量都在上下文(作用域)内,变量的命名要符合上下文。同一个变量在不同的上下文中可以有不同的命名。匈牙利符号。基本原则:变量名=属性+类型+描述。要求每个对象的名称具有明确的含义,可以使用对象的全称或缩写。例如:sUserName,一个表示用户名的字符串。有一定的学习成本,自己选择。.Constants 在ECMAScript6之前,JavaScript中并没有真正意义上的常量概念。但是,这并不妨碍开发人员将变量用作常量。为了区分普通变量(变量的值是可变的)和常量(常量的值在初始化后不能改变),一种通用的命名约定应运而生。这个约定来自C语言,它使用大写字母和下划线来分隔单词。按惯例命名。变量名全部使用大写字母,多个单词用下划线分隔魔法常量。同一个常量(值)在不同的上下文中可能代表不同的含义。延伸到js,就是用有意义的变量名代替魔法常量,来提高代码的可维护性和可读性。避免硬编码。对于在代码中多次复用,以后可能会发生变化的数据,最好将其分离成变量或配置项,实现代码逻辑与业务的松耦合,增强可维护性。常量声明。根据关键字的优先顺序:const=>let=>var。如果可以使用const和let,尽量不要使用var,因为var声明有副作用。注释 何时添加注释是一个有争议的问题。代码注释并不总是更好。(注:语义命名可以减少很多不必要的注释,最好的代码是不言自明的,不要过多追求注释,会影响代码的阅读。)代码难懂。当逻辑比较复杂或者业务逻辑比较特殊时,需要加上注释。重点是让其他人更容易理解这段代码。可能被误解的代码。在团队开发中,当你写的代码可能被其他同事认为错误时,你需要添加注释。浏览器功能破解。兼容性代码可能会造成混淆,应添加适当的注释来解释其用途。文档注释。对于工具类等公共方法,添加文档注释,说明其用途、参数、返回值等,让人通过阅读注释了解使用方法,而无需关心方法内部实现。函数 JS是一种多范式编程语言。函数式编程是一种编程范式,是一种构建计算机程序结构和元素的方法,它将计算视为数学函数的评估,并避免改变状态和可变数据。它使您能够构建无副作用的函数,并且函数式编程的一些优点还使系统更易于维护。纯函数。给定相同的参数,它返回相同的结果(确定性的);不会引起任何明显的副作用;易于测试。关闭。通过闭包,可以在函数外访问函数内部的变量,过度使用闭包会造成内存泄漏。单一原则。如果一个方法承担了太多的责任,它就更有可能需要随着需求的变化而被重写。面向方面的编程。无创改造功能。保持业务逻辑模块的纯度和高内聚性,其次,现有的功能模块可以方便地复用。鲁棒性。Web开发的经验法则:永远不要相信用户输入。最好对数据做异常处理,增强其健壮性。例如XSS。范围。形式参数越少越好,不超过3个,超过3个用对象代替,可以大大减少该方法的UT自测场景。注:尾调用和尾递归前端异常的处理 前端异常的处理也是代码健壮性的一部分。与Java不同,JavaScript有一种特殊的语法来定义和实现异常处理。前端代码是最贴近用户的代码。异常处理更多的是基于用户体验和代码健壮性。后端代码的异常处理更多的是从业务角度和数据安全出发。因此,JavaScript的异常处理方式主要是对页面内容(用户输入和界面输入)进行校验。可以根据页面提示快速定位和修复问题,提高解决问题的效率。使用同余===代替相等==(副作用) javascript有强制类型转换机制,判断相等的操作非常微妙。对于某些操作,为了获得成功的结果,强制类型转换会驱使某种类型的变量自动转换成其他不同的类型,这往往会导致意想不到的结果。 最常见的强制类型转换场景是使用判断相等运算符==和!=的时候。当被比较的两个值是不同类型时,两个运算符都有转换。但在许多实际情况下,代码的行为并不符合我的预期。Crockford的编程规范、jQuery核心风格指南和SproutCore编程风格指南推荐使用===和!==。jQuery效率提升建议正确使用选择器。id>tag>class>Attributesandpseudo-classes分层选择器尽量使用find方法,效率更高缓存jQuery对象链调用事件委托对DOM设计模式改动较少单例模式 设计模式旨在在软件设计过程中针对特定问题的简洁而优雅的解决方案。《parctical common lisp》的作者曾经说过,如果你需要一个模式,那就错了。他所指的问题是,由于语言本身的缺陷,必须寻求和总结一个通用的解决方案。无论是弱类型还是强类型、静态还是动态、命令式还是声明式,每种语言都有其固有的优点和缺点。 单例模式更容易理解。它是一个对象。创建这个对象的目的是为了管理系统代码中的一些公共变量、对象和函数,避免变量污染。一般我们声明一些变量和函数有时候,我们是在一个封闭的函数中,一般不会造成变量污染,但是为了以防万一,原因是在js中,全局变量和局部变量的关系比较复杂(有时候夹杂着一些变量提升的问题),很多coder经常因为这个问题出现bug,找了半天找不到原因。创建这个对象后,我们只对外暴露一个对象入口。在内部使用变量的时候,我们可以通过object的形式来调用变量。变量名。其实,它也是为了实现js代码块中命名空间的划分而设计的。 我之前写过几年的php和jQuery。在项目中不断摸索和总结后得出一个结论:在jQuery技术栈的实际项目开发中,近95%的需求都可以通过单例模式来满足实现。设计模式的适配器模式 适配器模式就是将一个类(对象)的接口(方法或属性)转换成客户所需要的另一个接口(方法或属性)。由于接口不兼容,适配器模式导致无法协同工作。那些类(对象)可以是一些工作。 适用场景:使用已有对象,但其方法或属性接口不符合您的要求。你想创建一个可重用的对象,它可以连接到其他不相关的对象或不可见的对象(即具有不兼容方法或属性的接口对象)一起工作以使用现有对象,但不能原型继承每个对象以匹配其接口。对象适配器可以适配其父对象接口方法或属性。推荐使用ES6,其次是ES5,最后ES3使用const,let,不使用var。静态字符串总是使用单引号或反引号,不使用双引号。当动态字符串使用反引号给使用数组成员的变量赋值时,优先考虑解构赋值,立即执行函数可以写成箭头函数的形式。对象尽量是静态的,一旦定义,就不能随意添加新的属性。如果添加属性是不可避免的,请使用Object.assign方法。使用扩展运算符(...)复制数组。VUE中的做法是简单易懂的语义标签,可以配合类名实现清晰简洁的层级结构,以最少的嵌套实现最复杂的结构最小化风格影响范围使用通俗的写法来降低学习成本尽量使用类选择器,少用标签选择器,实现CSS样式属性重用的顺序。请参考上一章《CSS中的实践》将视图显示的部分放在模板中,其中,视图层主要负责将数据(实体)在数据中进行显示和计算,数据层主要负责声明(interface,abstract)并将逻辑放在方法和其他几个API中,控制层主要负责实现单向数据流的思想。数据变更可记录追溯,溯源方便;数据只有一个入口和出口,更直观易懂,提高可维护性。注:95%的业务场景最多只需要用到3-4个生命周期。如果超过,查看自己的代码代码风格参考:https://cn.vuejs.org/v2/style...frontend前端框架在各个发展阶段的对比常见设计模式与代码的结合JavaScript语言语句特性的改进。代码执行时,js解析器会将函数声明和var声明放在最前面,然后依次执行相应的语句。推荐使用es6的const,后面接let,不推荐使用var。私有变量。闭包可以用来声明私有变量,但是闭包会让私有变量驻留在内存中,滥用闭包会导致内存泄漏,所以要慎用闭包。进。可以使用传统的for-in循环遍历对象,但是这种方法会遍历原型链上的属性,导致意想不到的结果。推荐使用ES6的Object.keys和Object.values结合数组API。多态的。JS没有多态性。从某种意义上说,多态是与函数的单一原则相对立的,所以当多种类型的参数执行同一类型的逻辑时,建议使用多态。参考:jquery源代码的Sizzle引擎。单线程。通过异步解决单线程的弊端。但是,传统的异步解决方案是通过回调实现的。大量嵌套的回调会造成回调地狱,代码可读性差,不利于维护。推荐使用ES6的Promise和async/await。副作用。全面拥抱函数式编程,避免使用有副作用的代码,比如ES3中的var声明提升,for-in的副作用,==的隐式转换,BOM中alert的阻塞作用等。书籍和社区《JavaScript权威指南》:Rhino书可以先粗略的看几遍,也可以当工具书,时不时翻看。《JavaScript高级程序设计》:小红书虽然号称进阶,但其实对入门很有帮助。小红书与犀牛书合作,相互印证。《你不知道的JavaScript 上中下》:这本书绝对是神书。它会让你了解JavaScript不为人知的另一面,把闭包和异步解释的很清楚。《ES6 标准入门(第3版)》阮老师的书,ES6入门书。《锋利的jQuery》循序渐进介绍jQuery的各种API《 JavaScript模式》陈欣怡,系统讲解编写高质量代码的技巧和开发过程中最常用的设计模式。《重构-改善既有代码的设计》写代码的一些思想层面的东西。《编写可维护的JavaScript 》包括具体风格和原理的介绍,以及示例和技术讲解思府社区:中文版stackoverflow心得和心得 软件bug修改是需要成本的,而且这个成本一直在增加,尤其是对于已广泛发布的产品代码。最好的情况是当我们发现一个错误时,我们可以立即修复它,这只会发生在编写代码后不久。否则,转移到一个新任务,忘记这部分代码,需要重新阅读代码。 对于大型项目,还有一个问题,就是最后修改代码的人往往不是一开始写代码的人,也不是发现bug的人。所以,减少理解之前自己写的代码的时间,或者减少理解团队里其他人写的代码的时间,就变得非常关键了。 另一个事实是,软件开发人员通常花在阅读代码上的时间多于编写代码的时间。通常,当我们专注于一个问题时,我们会坐下来花一个下午的时间编写大量代码。代码可能当天就可以运行,但要成为成熟的应用程序,我们需要重新检查、重新校准和重新调整代码。 编写高质量的代码非常重要,不仅是为了项目的顺利完成,也是为了开发者与开发团队其他成员的交流。提高代码质量可能需要几个小时的工时来编写,但最终需要数周的工时来阅读。这就是为什么编写易于维护的高质量代码在项目中起着举足轻重的作用。 代码的质量在某种意义上是一个系统的生命线。任何上线的系统都通过了测试,但代码的好坏决定了系统能走多远!我在新闻里听说过有人删库跑路,也见过有人接手老项目就立马走人。其中一些必然与旧代码的质量问题有关。 代码质量和效率之间存在着天然的矛盾。如何平衡,值得思考。以下是我的心得体会:1.代码风格;2、代码审查;3.提取、包装、再利用;4、不断学习,不断实践;5.开发周期与代码质量的平衡。
