JS的几种写法

1. 按强类型风格写代码
JS 是弱类型的,但是写代码的时候不能太随意,哈乐鱼写得太随意也体现了编码风格不好。下面分点说明:
(1)定义变量的时候要指明类型,告诉 JS 解释器这个变量是什么数据类型的,而不要让解释器去猜,例如不好的写法:


声明了三个变量,但其实没什么用,因为解释器不知道它们是什么类型的,好的写法应该是这样的:


定义变量的时候就给他一个默认值,这样不仅方便了解释器,也方便了阅读代码的人,他会在心里有数——知道这些变量可能会当作什么用。

(2)不要随意地改变变量的类型,例如下面代码:


第 1 行它是一个整型,第 2 行它变成了一个字符串。因为 JS 最终都会被解释成汇编的语言,汇编语言变量的类型肯定是要确定的,你把一个整型的改成了字符串,那解释器就得做一些额外的处理。并且这种编码风格是不提倡的,有一个变量第 1 行是一个整型,第 10 行变成了一个字符串,第 20 行又变成了一个 object,这样就让阅读代码的人比较困惑,上面明明是一个整数,怎么突然又变成一个字符串了。好的写法应该是再定义一个字符串的变量:

(3)函数的返回类型应该是要确定的,例如下面不确定的写法:

getPrice 这个函数有可能返回一个整数,也有可能返回一个空的字符串。这样写也不太好,虽然它是符合 JS 语法的,但这种编码风格是不好的。使用你这个函数的人会有点无所适从,不敢直接进行加减乘除,因为如果返回字符串进行运算的话值就是 NaN 了。函数的返回类型应该是要确定的,如下面是返回整型
上面用了一个 function 制造一个局部作用域,也可以用 ES6 的块级作用域。由于 map 这个变量直接在当前的局部作用域命中了,所以就不用再往上一级的作用域(这里是全局作用域)查找了,而局部作用域的查找是很快的。同时直接在全局作用域定义变量,会污染 window 对象。

(2)不要滥用闭包
闭包的作用在于可以让子级作用域使用它父级作用域的变量,同时这些变量在不同的闭包是不可见的。这样就导致了在查找某个变量的时候,如果当前作用域找不到,就得往它的父级作用域查找,一级一级地往上直到找到了,或者到了全局作用域还没找到。因此如果闭包嵌套得越深,那么变量查找的时间就越长。


上面的代码定义了一个 process 函数,在这个函数里面 count 变量的查找时间要高于局部的 factor 变量。其实这里不太适合用闭包,可以直接把 count 传给 process:


这样 count 的查找时间就和 factor 一样,都是在当前作用域直接命中。这个就启示我们如果某个全局变量需要频繁地被使用的时候,可以用一个局部变量缓存一下,如下:

上面的两个例子都是确定类型的,一个是字符串,一个是整数。就没必要使用==了,直接用===就可以了。

(2)如果类型不确定,那么应该手动做一下类型转换,而不是让别人或者以后的你去猜这里面有类型转换,如下:


(3)使用==在 JSLint 检查的时候是不通过的:

 

(4)并且使用==可能会出现一些奇怪的现象,这些奇怪的现象可能会给代码埋入隐患:


上面的比较在用===的时候都是 false,这样才是比较合理的。例如第一点 null 居然会等于 undefined,就特别地奇怪,因为 null 和 undefined 是两个毫无关系的值,null 应该是作为初始化空值使用,而 undefined 是用于检验某个变量是否未定义。这和第 1 点介绍强类型的思想是相通的。

4. 合并表达式
如果用 1 句代码就可以实现 5 句代码的功能,那往往 1 句代码的执行效率会比较高,并且可读性可能会更好

(1)用三目运算符取代简单的 if-else
如上面的 getPrice 函数:


这个比写一个 if-else 看起来清爽多了。当然,如果你写了 if-else,压缩工具也会帮你把它改三目运算符的形式:

(2)连等
连等是利用赋值运算表达式会返回所赋的值,并且执行顺序是从右到左的,如下:

有时候你会看到有人这样写:


也是利用了赋值表达式会返回一个值,在 if 里面赋值的同时用它的返回值做判断,然后 else 里面就已经有值了。上面的+号把字符串转成了整数。

(3)自增
利用自增也可以简化代码。如下,每发出一条消息,localMsgId 就自增 1:


5. 减少魔数
例如,在某个文件的第 800 行,冒出来了一句:

dialogHandler.showQuestionNaire("seller", "sell", 5, true);
就会让人很困惑了,上面的四个常量分别代表什么呢,如果我不去查一个那个函数的变量说明就不能够很快地意会到这些常量分别有什么用。这些意义不明的常量就叫“魔数”。所以最好还是给这些常量取一个名字,特别是在一些比较关键的地方。例如上面的代码可改成:

这样意义就很明显了。

6. 使用 ES6 简化代码
ES6 已经发展很多年了,兼容性也已经很好了。恰当地使用,可以让代码更加地简洁优雅。

(1)使用箭头函数取代小函数
有很多使用小函数的场景,如果写个 function,代码起码得写 3 行,但是用箭头函数一行就搞定了,例如实现数组从大到小排序:


var nums = [4, 8, 1, 9, 0];``nums.sort(a, b => b - a);
代码看起来简洁多了,还有 setTimeout 里面经常会遇到只要执行一行代码就好了,写个 function 总感觉有点麻烦,用字符串的方式又不太好,所以这种情况用箭头函数也很方便:

setTimeout(() => console.log("hi"), 3000)
箭头函数在 C++/Java 等其它语言里面叫做 Lambda 表达式,Ruby 比较早就有这种语法形式了,后来 C++/Java 也实现了这种语法。当然箭头函数或者 Lambda 表达式不仅适用于这种一行的,多行代码也可以,不过在一行的时候它的优点才比较明显。

(2)使用 ES6 的 class
虽然 ES6 的 class 和使用 function 的 prototype 本质上是一样的,都是用的原型。但是用 class 可以减少代码量,同时让代码看起来更加地高大上,使用 function 要写这么多.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章