3个编写JavaScript高质量代码的技巧,让你不再996
本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!
前段时间有一个叫做“人类高质量男性”的视频火了,相信很多同学都刷到过。所以今天给大家分享下,什么叫做“人类高质量代码”,哈哈,开个玩笑。
其实分享的都是一些自己平时总结的小技巧,算是抛砖引玉吧,希望能给大家带来一些启发和帮助。
如何编写出高质量的 JavaScript 代码?我个人认为,如果要编写出高质量的 JavaScript 代码,可以从以下三个方面去考虑。
分别是:易阅读的代码、高性能的代码、健壮性的代码。下面我将分别对这三个方面进行阐述。
易阅读的代码
首先说一下,代码是写给自己或团队成员看的,良好的阅读方式是编写高质量代码的前提条件。这里总结了四点具体操作方式分享给大家。
第一点:统一代码格式
不要一会这样写,一会那样写,尽量统一写法,下面举例。
人为去约定代码格式,是很不方便的,所以可以借助一些工具进行自动格式转换。
魔术数字(magic number)是程式设计中所谓的直接写在程式码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程式作者写的时候自己能了解数值的意义,但对其他程式员而言,甚至作者本人经过一段时间后,都会很难理解这个数值的用途。
当然还有魔术字符串也是像上面一样去处理,上面代码中的常量命名推荐采用下划线命名的方式,其他如变量、函数等推荐用驼峰进行命名。
其实减少this的使用频率也是一样的道理,当代码中充斥着大量this的时候,我们往往很难知道它是谁,需要花费很多时间进行阅读。
无论是编写模块、类、还是函数都应该让他们各自都只有单一的功能,不要让他们做过多的事情,这样阅读起来会非常简单,扩展起来也会非常灵活。
多层级的嵌套,如:条件嵌套、循环嵌套、回调嵌套等,对于代码阅读是非常不利的,所以应尽量减少嵌套的层级。
像解决条件嵌套的问题,一般可采用卫语句(guard clause)的方式提前返回,从而减少嵌套。
除了卫语句外,通过还可以采用短路运算、条件运算符等进行条件语句的改写。
像解决回调嵌套的问题,一般可采用“async/await”方式进行改写。
除了以上介绍的四点建议外,还有很多可以改善阅读体验的点,如:有效的注释、避免不同类型的比较、避免生涩的语法等等。
在软件开发中,代码的性能高低会直接影响到产品的用户体验,所以高质量的代码必然是高性能的。这里总结了四点具体操作方式分享给大家。
提示:测试JavaScript平均耗时,可使用console.time()方法、JSBench.Me工具、performance工具等。
递归是一种常见的算法,下面是用递归实现的“求阶乘”的操作。
“尾调用”是一种可以重用栈帧的内存管理优化机制,即外部函数的返回值是一个内部函数的返回值。
很多功能都可以采用JavaScript内置方法来解决,往往内置方法的底层实现是最优的,并且内置方法可在解释器中提前执行,所以执行效率非常高。
下面举例为:获取对象属性和值的复合数组形式。
作用域链是作用域规则的实现,通过作用域链的实现,变量在它的作用域内可被访问,函数在它的作用域内可被调用。作用域链是一个只能单向访问的链表,这个链表上的每个节点就是执行上下文的变量对象(代码执行时就是活动对象),单向链表的头部(可被第一个访问的节点)始终都是当前正在被调用执行的函数的变量对象(活动对象),尾部始终是全局活动对象。
概念太复杂的话, 看下面这样一张图。
作用域链这个链表就是 3(头部:bar) -> 2(foo) -> 1(尾部:全局),所以查找变量的时候,应尽量在头部完成获取,这样就可以节省性能,具体对比如下。
除了减少作用域链查找外,减少对象属性的查找也是一样的道理。
有时候编写程序时,会出现很多重复执行的代码,最好要避免做重复操作。先举一个简单的例子,通过循环找到第一个满足条件元素的索引位置。
再来看一个计算“斐波那契数列”的案例。
这里把递归执行过的结果缓存到数组中,这样接下来重复的代码就可以直接读取缓存中的数据了,从而大幅度提升性能。
画叉号的部分就会走缓存,而不会重复执行计算。
除了以上介绍的四点建议外,还有很多可以改善代码性能的点,如:减少DOM操作、节流处理、事件委托等等。
所谓健壮性的代码,就是编写出来的代码,是可扩展、可维护、可测试的代码。这里总结了四点具体操作方式分享给大家。
很多新语法可弥补之前语法的BUG,让代码更加健壮,应对未来。
由于产品需求总是会有新的变更,对软件的可扩展能力提出了很高要求,所以健壮的代码都是可以随时做出调整的代码。
当函数产生了除了“接收一个值并返回一个结果”之外的行为时,就产生了副作用。副作用不是说一定是有害的,但是如果在项目中没有节制的引起副作用,代码出错的可能性会非常大。
建议尽量不要去修改全局变量或可变对象,通过参数和return完成需求。让函数成为一种纯函数,这样也可使代码更容易被测试。
当项目过于复杂的时候,经常会把各种逻辑混在一起,对后续扩展非常不利,而且还影响对代码的理解。所以尽量把相关的逻辑抽离到一起,进行集中式的管理。像React中的hooks,Vue3中的Composition API都是采用这样的思想。
除了以上介绍的四点建议外,还有很多可以改善代码健壮性的点,如:异常处理、单元测试、使用TS替换JS等等。
最后总结一下,如何编写高质量JavaScript代码:
欢迎关注「慕课网」,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!
127个常用的JS代码片段,每段代码花30秒就能看懂(一)
JavaScript 是目前最流行的编程语言之一,正如大多数人所说:“如果你想学一门编程语言,请学JavaScript。”
FreeCodeCamp的创始人 Quincy Larson 在最近的一次采访中被问到哪种语言开发人员应该首先学习。他回答:“ JavaScript。”
“软件正在吞噬世界,JavaScript正在吞噬软件。JavaScript每年都在变得越来越占主导地位,而且没人知道最终会取代它的是什么。\” 如果您没有充分的理由学习一种新语言(例如您的工作要求您维护非JavaScript代码库),那么我的建议是着重于提高JavaScript的水平。”
听我说这么多,你是不是很激动呢。这里有127端常用的JS代码片段,方便你学习和使用。
如果数组所有元素满足函数条件,则返回true。调用时,如果省略第二个参数,则默认传递布尔值。
判断数组中的元素是否都相等
此代码示例检查两个数字是否近似相等,差异值可以通过传参的形式进行设置
此段代码将没有逗号或双引号的元素转换成带有逗号分隔符的字符串即CSV格式识别的形式。
此段代码将数组元素转换成<li>标记,并将此元素添加至给定的ID元素标记内。
此段代码执行一个函数,将剩余的参数传回函数当参数,返回相应的结果,并能捕获异常。
此段代码返回两个或多个数的平均数。
一个 map()函数和 reduce()函数结合的例子,此函数先通过 map() 函数将对象转换成数组,然后在调用reduce()函数进行累加,然后根据数组长度返回平均值。
此函数包含两个参数,类型都为数组,依据第二个参数的真假条件,将一个参数的数组进行分组,条件为真的放入第一个数组,其它的放入第二个数组。这里运用了Array.prototype.reduce() 和 Array.prototype.push() 相结合的形式。
此段代码将数组按照指定的函数逻辑进行分组,满足函数条件的逻辑为真,放入第一个数组中,其它不满足的放入第二个数组 。这里运用了Array.prototype.reduce() 和 Array.prototype.push() 相结合的形式,基于函数过滤逻辑,通过 Array.prototype.push() 函数将其添加到数组中。
用于检测页面是否滚动到页面底部。
此代码返回字符串的字节长度。这里用到了Blob对象,Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(比如File对象),都是建立在Blob对象基础上的,继承了它的属性和方法。生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。
将字符串的首字母转成大写,这里主要运用到了ES6的展开语法在数组中的运用。
将一个句子中每个单词首字母转换成大写字母,这里中要运用了正则表达式进行替换。
此段代码将非数值的值转换成数组对象。
将数组中移除值为 false 的内容。
统计数组中某个值出现的次数
此代码段使用 existSync() 检查目录是否存在,然后使用 mkdirSync() 创建目录(如果不存在)。
返回当前访问的 URL 地址。
返回当前是今年的第几天
将字符串的首字母转换成小写字母
今天的内容就和大家分享到这里,感谢你的阅读,如果你喜欢我的分享,麻烦给个关注、点赞加转发哦,你的支持,就是我分享的动力,后续会持续分享剩余的代码片段,欢迎持续关注。
本文原作者:Fatos Morina
来源网站:medium
注:并非直译
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。