现在读动物书,有一种崇敬的感觉前言 整体来说,《重构 JavaScript》对从刚入门到有些许开发经验的人,都有受益的地方。
前面讲述了在 JavaScript 里重构是一个什么概念,你应该怎么选择、学习和使用 JavaScript,以及讲测试对重构的重要性;中间讲述了重构的目标、要注意的结构和一些值得注意的点;最后提到了一些异步、模式和函数式编程的思路。
可以这样形容:有一个密室,给你一些物品,然后从上帝视角告诉你物品的作用,以及你可以选择或参考的路线,也包括你可能走过的错误路线分析,最后告诉你如何走的更漂亮。
其中比较有感触的地方就是:要相信你的代码,不要害怕测试,遵循一些特定的规范和模式,就可以把你的代码重构下去,如果愿意再学习一些新的思路,你的代码会更漂亮,你的项目会更健壮,你的技术(包括思想)会有质的飞跃。
介绍 下图是一张图书简介(取自某个在线商城):
文章图片
摘录 以下是文章里的一些摘录,个人感觉有很多值得学习和思考的地方,当然其中也有个人理解的成分。(部分专业术语没有做具体的介绍,因为太多了......)
第1章: 重构是什么?
- 当我们进行测试时,我们有足够的信心重构代码并改变实现。如果没有这些测试,我们就是把我们真正关心的行为(输入和输出)置于危险之中。
- 性能(和其他非功能性方面)是我们决定围绕它创建期望和测试的次要问题。
- 在过去的20年里,一个流行的比喻是技术债。
- 高质量的代码一般都有以下原则:
- SOLID:单一职责原则,开闭原则,里氏替换原则,接口隔离原则,依赖反转原则。
- DRY:不做重复的事。
- KISS:保持简单直接。
- GRASP:通用职责分配软件模式。
- YAGNI:你不会需要它。
- 将人的可读性视为质量
- 重构即探索
- 我应该使用哪个框架?
这是JavaScript 开发者经常提出的一个问题,而且可能是来自新开发人员最大的 问题,“我应该学习哪种语言?” 框架限定的工作方式可以给程序员一种他们 真的知道一切的感觉。用夸张甚至矛盾的要求来描述工作没有什么用。当涉及 JavaScript 时有很多框架、平台和最终不同类型的代码,你可能都会写到,这个 问题的某些形式会一次又一次地出现。
最后,你不可能学会一切。如果你有一个工作或目标工作真正需要某些技能,首 先花时间在那些事上面。如果你心中没有一份特别的工作,去聚会找朋友和导师, 并跟着他们做。或者,如果你只想学习你感兴趣的东西,选择一些看起来很酷的 东西,然后深入进去,继续前进,在某个时候,考愿娴熟掌握这些技术。
你可以在语言、框架、测试库或乐器上应用相同的过程(按照工作要求、朋友在 使用的和你认为酷的进行过滤)。在所有这些中,偶尔深入,如果你原谅一些粗 鲁的建议,请注意哪里钱多。
“看起来很酷” 可能听起来很模糊,确实如此。对我来说,这意味着要找到最新 奇或者最令人费解的技术。我不太可能学习14 种解决相同问题的变体。对一些 人来说,酷意味着新和时髦。对其他人来说,它意味着受欢迎或有利可图。如果 你不知道 “看起来很酷” 对你来说意味着什么,那就用一些可能性来解决这个问 题,而不是花太多时间考虑选择哪一个。
- 框架这个术语被看得过重了。
- 关于最后一个引用。
测试不是个问题。这种现象暗示了这是一个缺乏领导力的小型或缺乏经验团队。
不幸的是,如果你在一个都是莽撞的人的团队中(这些程序员只是堆砌代码,而不重视质量和测试),最可能的结果是挫败感和不可预测的破坏(以及不可预知的时间)。
“立即离开这个不好的团队” 不是唯一的答案,因为在这种情况下可能还有其他的好处和限制。但是一些注重质量的项目往往有更好的稳定性(更少的推翻重来),更好的薪酬和更多学习的机会。
正常的老板或客户不会拒绝任何对软件是否正常工作的验证。
- 就像伊索寓言里的狐狸一样,没有抓到葡萄的时候,就说它们一定是酸的。如果保证软件质量的测试是很难的,那就一定是不重要的,对吗?这可能对让你面对人生中你无法控制的遗憾和失望是有帮助的,但如果没有认识到测试的好处,你就无法以一个完全不同的方式来写代码。葡萄不是酸的,不要像那只狐狸一样,你是可以找到一个梯子实现的。
- 测试的主要目的是对代码有信心。 这种信心不是凭空产生的。它是由看到错误和抵制变化的代码而产生的怀疑中形成的。信心是测试什么和如何测试的最佳指标。了解测试的最大原因是帮助你在查看代码库时建立自信和怀疑感。
- 每个测试方法都有三个阶段:设置、断言和回收。
- 在TDD(测试驱动开发)中,可以使用 红色/绿色/重构 周期来测试代码,换句话说:“测试失败,测试成功,优化之”。
- 在任何情况下,请保持
git commit
命令之间的步骤很小,以便你可以很容易回滚到干净的版本。
- 相比只返回
undefined
,返回this
将提供更多的信息和更好的接口。 - 理想情况下,副作用 越少越好,如果必须存在,应该尽可能做到隔离。
IIFEs
没有名字,也不能被寻址。- 类有更多的特性,这些特性构成了独特的构造,而不仅仅是构造函数的 “语法糖”。
- JavaScript 在 OOP 上翻了一番,函数式编程可能是 JavaScript 的 “未来”,但至少 OOP 也是未来。
- 尽量减少块(复杂度和代码行数)。
- 尽量减少输入的总数。
- 多使用显示输入。
- 相比副作用,多使用真实有意义的返回值。
- 将副作用降低到最小甚至不存在。
- 重命名 可能是件大事。
- 注释 有时候可以用作文档,甚至可以建立外部文档。
- “提取” 是一种特定类型的 “引入”,有时候它比函数更合适。
- 要注意 变量提升。
- “for in” 有点像我们的 for 和 while 循环,但是我们没有处理索引更新,所以你可以把它看成 “for 索引 in”。
- for...in 中的索引不保证按顺序。
- 任何可枚举的属性都将被枚举,数组可以从其他地方继承 “enumerable” 属性。
- 在 for...in 循环中修改数组可能会导致混淆。
- 映射(Map)是为了实现更轻量级的 “键和值” 。
- 【《重构 JavaScript》读后感和部分摘录】
WeakSet
和WeakMap
与它们的 “强” 版本的主要区别是:
- 它们不能被迭代(没有
forEach
函数)。 - 它们没有获取容器大小的引用。
- WeakSet 不能存储基本类型数据。
- 他们很 “弱” 地管理它们的键。也就是说,当键没有任何引用的时候可以被垃圾回收。
- 它们不能被迭代(没有
- 使用 “弱” 形式时,你放弃了容易了解内部是什么或将函数应用到整个集合的能力。而你得到的是对内存泄漏和隐私的控制。
- 建议将 if 中多个布尔值的判断放到一个函数的返回值中。
- 尽量缩小全局变量的作用域,最好可以设计我们的API。
- 要构建好逻辑的层次结构,尽量隔离。
- 构造函数经常会在原型上搞事情,所以不要它不是很好用,可以使用对象字面量和工厂函数来代替。
- 考虑好
Is-A
和Is-Just-A
。
- 状态模式 的核心是愿意将可能被认为是 “属于” 某个对象的部分移动到另一个对象中。 OOP (面向对象编程)中有一种倾向,即将层次结构放在委托对象的优先级之上。
- 装饰器 主要表现在将特性添加到现有的接口(实例)中。
- 外观 (对象字面量的方式来定义)看起来很简洁,坏处是不容易维护。
- 将 “回调地狱” 变成 流式API,这种风格叫 CPS(延续传递风格)。
Promise
的价值在于它们改变了接口,而这些可能就是你希望进行测试的地方。
- 在 FP(声明式编程)中,我们应该试图去强调,描述一个程序应该做什么,而不是应该怎么做。
- 纯函数的好处是幂等性,也就是作用域够小并且不能改变时,你可以总是相信同样的参数进去,返回的结果是一样的。另一个好处就是不产生副作用。
- 柯里化、函数组合是个好想法。
希望大家都可以成为心目中的大佬!
推荐阅读
- DNS域名解析过程简述
- 如何实现一个简单的发布订阅模式
- 选择篇(041)-下面代码的输出是什么?
- 首屏时间,你说你优化了,那你倒是计算出给给我看啊!
- 选择篇(021)-下面代码的输出是什么?
- 精读《zustand 源码》
- 浅谈js的垃圾回收机制
- 选择篇(017)-哪个选项是不正确的?
- JavaScript笔记之如何写好JavaScript