-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2016/03/31 针针见血:怎么消除JavaScript中的代码坏味道 #5
Comments
第一个例子是不是有误? |
肿么感觉,看着糟糕代码都是我会写的,心好累 |
我也是这种感觉,槽糕的代码都是我现在在写的 |
|
@flyinhigh 哈哈,前面那个其实是包含 es6 的 template string 的语法(内插值)啦,去了解下就知道了~ |
写得很棒~一点儿小意见...
|
@BuptStEve 很仔细。用新的includes很好,来清除掉怪异的!! |
这个不是去年jsconf的js code smells的ppt吗? http://elijahmanor.com/javascript-smells/ 是不是说明在文章开头原作者和来源好一点? |
@chengmu 说的很对,现在的文章都会在开头说明来源。老文章并没有这些意识 /(ㄒoㄒ)/~~ |
本文罗列JavaScript代码中常见的代码坏味道,如临时定时器,双向数据绑定的坑,复杂的分支语句,重复赋值等,对它们进行分析如现场还原,糟糕代码回顾,问题诊断和识别(通过ESlint或其他工具),代码重构方案,给出了怎么写好代码的一手经验~
绕来绕去,很烧脑
问题现场:
如果单词以辅音开头(或辅音集),把它剩余的步伐移到前面,并且添加上『ay』如pig -> igpay
如果单词以元音开头,保持顺序但是在结尾加上『way』如,egg->eggway等
糟糕代码:
问题在哪:
检测出问题:
关于Lint的配置项:如最大语句数,复杂度,最大嵌套数,最大长度,最多传参,最多嵌套回调
测试先行:
重构后代码:
数据对比:
max-statements: 16 → 6
max-depth: 5 → 2
complexity: 7 → 3
max-len: 65 → 73
max-params: 1 → 2
max-nested-callbacks: 0 → 1
相关资源:
jshint - http://jshint.com/
eslint - http://eslint.org/
jscomplexity - http://jscomplexity.org/
escomplex - https://github.com/philbooth/escomplex
jasmine - http://jasmine.github.io/
粘贴复制
问题现场:
我们需要实现如下的效果

糟糕的代码:
问题出在哪:
因为我们在粘贴复制!!
检测出问题:
检查出粘贴复制和结构类似的代码片段 - jsinspect
https://github.com/danielstjules

从你的JS,TypeScript,C#,Ruby,CSS,HTML等源代码中找到粘贴复制的部分 - JSCPD
https://github.com/kucherenko/jscpd

重构后代码:
复杂的分支语句
糟糕的代码:
问题出在哪:
违反了 open/close 原则:
软件元素(类,模块和方法等)应该易于被打开扩展,但是除了本身不要多于的修改。既代码本身可以允许它的行为被扩展,但是不要修改源代码
可以使用诸如检查:
no-switch - disallow the use of the switch statement
no-complex-switch-case - disallow use of complex switch statements
重构后代码:
这时候添加一个代码就不像之前那样该原先的switch,直到它又长又臭,还容易把之前的代码逻辑broken掉。
魔法数字/字符串的坏味道
糟糕代码:
如上面看到的,如Magic Strings,对于诸如Triangle,Square这些就是特殊字符串。
问题出在哪:
这些魔法数字和字符串是直接写死在代码中,不容易修改和阅读。注入password.length > 9,这里面的9是指 MAX_PASSWORD_SIZE ,这样先定义后使用更清晰。同时如果多个地方需要这个判断规则,也可以避免多次修改类似9这样的数字
https://en.wikipedia.org/wiki/Magic_number_(programming)
http://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad
重构后代码:
1 通过对象
2 通过 const 和 symbols
代码深渊
糟糕代码:
问题出在哪:
奇奇怪怪的 self /that/_this 等
使用一下的eslint:
重构后代码:
利用Function.bind, 2nd parameter of forEach, es6
脆裂的字符拼接
糟糕代码:
问题出在哪:
代码很丑陋,也很啰嗦,不直观。
使用 ES6的模板字符串(字符串插值和多行)
很多工具和框架也都提供了响应的支持,如lodash/underscore,angular,react 等
重构后代码:
jQuery询问
糟糕代码:
问题出在哪:
太多的链式调用
重构后代码:
临时定时器
糟糕代码:
问题出在哪:
out of sync timer 不能确认时序和执行
重构后代码:
等 3s 去执行timer(setTimeout),然后调用 someLongProcess (long process: random time ),接着在循环
使用setInterval fn(其中在进行 long process),还是通过callback传递来反复setTimeout(timer, )
重复赋值
糟糕代码:
问题出在哪:
有些重复和啰嗦
eslint-plugin-smells
重构后代码:
1 嵌套的函数调用
2 forEach
3 reduce
4 flow
不合理的情报
糟糕代码:
问题出在哪:
依赖被紧紧的耦合了
相互调用,耦合!如 product 和 shoppingCart 关系
重构后代码:
1 dependency injection 依赖注入
2 消息经纪人broker
不断的交互调用
糟糕代码:
问题出在哪:
会造成卡顿,多余的计算等
重构后代码:
throttle 和 debounce
匿名算法
糟糕代码:
问题出在哪:
匿名函数是个好东西,但是给函数命名可以帮助我们:
重构后代码:
未明确的执行
糟糕代码:
明确触发时机而不是,写在 domready
问题出在哪:
很难做单元测试
重构后代码:
利用单例模块,加上构建器函数
单例模式(单例有个init 方法,来Kick off) & 构造函数(new Application() -> 在原来的构造函数中Kick off your code!)
双向数据绑定
糟糕代码:
随便看看你们手头的MVVM项目(如Angular的等)
问题出在哪:
很难定位执行顺序和数据流(Hard to track execution & data flow )
(也是Angular1.x被大力吐槽的地方,被React的Flux)
重构后代码:
方案: flux(action, dispatcher, store->view)
React Flux
An Angular2 Todo App: First look at App Development in Angular2
结语
更多的lint规则,在npm上搜索 eslint-plugin 查找
Reference
The text was updated successfully, but these errors were encountered: