《重构 JavaScript》读后感和部分摘录

Mar 1, 2022
#refacor  #js 

前言

整体来说,《重构 JavaScript》对从刚入门到有些许开发经验的人,都有受益的地方。

前面讲述了在 JavaScript 里重构是一个什么概念,你应该怎么选择、学习和使用 JavaScript,以及讲测试对重构的重要性;中间讲述了重构的目标、要注意的结构和一些值得注意的点;最后提到了一些异步、模式和函数式编程的思路。

可以这样形容:有一个密室,给你一些物品,然后从上帝视角告诉你物品的作用,以及你可以选择或参考的路线,也包括你可能走过的错误路线分析,最后告诉你如何走的更漂亮。

其中比较有感触的地方就是:要相信你的代码,不要害怕测试,遵循一些特定的规范和模式,就可以把你的代码重构下去,如果愿意再学习一些新的思路,你的代码会更漂亮,你的项目会更健壮,你的技术(包括思想)会有质的飞跃。

介绍

下图是一张图书简介(取自某个在线商城):

摘录

以下是文章里的一些摘录,个人感觉有很多值得学习和思考的地方,当然其中也有个人理解的成分。(部分专业术语没有做具体的介绍,因为太多了......)

第1章: 重构是什么?

  • 当我们进行测试时,我们有足够的信心重构代码并改变实现。如果没有这些测试,我们就是把我们真正关心的行为(输入和输出)置于危险之中。

  • 性能(和其他非功能性方面)是我们决定围绕它创建期望和测试的次要问题。

  • 在过去的20年里,一个流行的比喻是技术债

  • 高质量的代码一般都有以下原则:

    • SOLID:单一职责原则,开闭原则,里氏替换原则,接口隔离原则,依赖反转原则。
    • DRY:不做重复的事。
    • KISS:保持简单直接。
    • GRASP:通用职责分配软件模式。
    • YAGNI:你不会需要它。
  • 将人的可读性视为质量

  • 重构即探索

第2章:你使用哪种JavaScript?

  • 我应该使用哪个框架?

    这是JavaScript 开发者经常提出的一个问题,而且可能是来自新开发人员最大的 问题,“我应该学习哪种语言?” 框架限定的工作方式可以给程序员一种他们 真的知道一切的感觉。用夸张甚至矛盾的要求来描述工作没有什么用。当涉及 JavaScript 时有很多框架、平台和最终不同类型的代码,你可能都会写到,这个 问题的某些形式会一次又一次地出现。

    最后,你不可能学会一切。如果你有一个工作或目标工作真正需要某些技能,首 先花时间在那些事上面。如果你心中没有一份特别的工作,去聚会找朋友和导师并跟着他们做。或者,如果你只想学习你感兴趣的东西,选择一些看起来很酷的 东西,然后深入进去,继续前进,在某个时候,考愿娴熟掌握这些技术。

    你可以在语言、框架、测试库或乐器上应用相同的过程(按照工作要求、朋友在 使用的和你认为酷的进行过滤)。在所有这些中,偶尔深入,如果你原谅一些粗 鲁的建议,请注意哪里钱多

    “看起来很酷” 可能听起来很模糊,确实如此。对我来说,这意味着要找到最新 奇或者最令人费解的技术。我不太可能学习14 种解决相同问题的变体。对一些 人来说,酷意味着新和时髦。对其他人来说,它意味着受欢迎或有利可图。如果 你不知道 “看起来很酷” 对你来说意味着什么,那就用一些可能性来解决这个问 题,而不是花太多时间考虑选择哪一个

  • 框架这个术语被看得过重了。

第3章:测试

  • 关于最后一个引用。

    测试不是个问题。这种现象暗示了这是一个缺乏领导力的小型或缺乏经验团队

    不幸的是,如果你在一个都是莽撞的人的团队中(这些程序员只是堆砌代码,而不重视质量和测试),最可能的结果是挫败感和不可预测的破坏(以及不可预知的时间)。

    “立即离开这个不好的团队” 不是唯一的答案,因为在这种情况下可能还有其他的好处和限制。但是一些注重质量的项目往往有更好的稳定性(更少的推翻重来),更好的薪酬和更多学习的机会。

    正常的老板或客户不会拒绝任何对软件是否正常工作的验证。

  • 就像伊索寓言里的狐狸一样,没有抓到葡萄的时候,就说它们一定是酸的。如果保证软件质量的测试是很难的,那就一定是不重要的,对吗?这可能对让你面对人生中你无法控制的遗憾和失望是有帮助的,但如果没有认识到测试的好处,你就无法以一个完全不同的方式来写代码。葡萄不是酸的,不要像那只狐狸一样,你是可以找到一个梯子实现的。

  • 测试的主要目的是对代码有信心。 这种信心不是凭空产生的。它是由看到错误和抵制变化的代码而产生的怀疑中形成的。信心是测试什么和如何测试的最佳指标。了解测试的最大原因是帮助你在查看代码库时建立自信和怀疑感。

  • 每个测试方法都有三个阶段:设置、断言和回收。

第4章:测试实践

  • 在TDD(测试驱动开发)中,可以使用 红色/绿色/重构 周期来测试代码,换句话说:“测试失败,测试成功,优化之”。
  • 在任何情况下,请保持 git commit 命令之间的步骤很小,以便你可以很容易回滚到干净的版本。

第5章:基本重构目标

  • 相比只返回 undefined,返回 this 将提供更多的信息和更好的接口。
  • 理想情况下,副作用 越少越好,如果必须存在,应该尽可能做到隔离。
  • IIFEs 没有名字,也不能被寻址。
  • 类有更多的特性,这些特性构成了独特的构造,而不仅仅是构造函数的 “语法糖”。
  • JavaScript 在 OOP 上翻了一番,函数式编程可能是 JavaScript 的 “未来”,但至少 OOP 也是未来。
  • 尽量减少块(复杂度和代码行数)。
  • 尽量减少输入的总数。
  • 多使用显示输入。
  • 相比副作用,多使用真实有意义的返回值。
  • 将副作用降低到最小甚至不存在。

第6章:重构基本结构

  • 重命名 可能是件大事。

  • 注释 有时候可以用作文档,甚至可以建立外部文档。

  • “提取” 是一种特定类型的 “引入”,有时候它比函数更合适。

  • 要注意 变量提升

  • “for in” 有点像我们的 for 和 while 循环,但是我们没有处理索引更新,所以你可以把它看成 “for 索引 in”。

    • for...in 中的索引不保证按顺序。
    • 任何可枚举的属性都将被枚举,数组可以从其他地方继承 “enumerable” 属性。
    • 在 for...in 循环中修改数组可能会导致混淆。

第7章:重构函数与对象

  • 映射(Map)是为了实现更轻量级的 “键和值” 。

  • WeakSetWeakMap 与它们的 “强” 版本的主要区别是:

    • 它们不能被迭代(没有 forEach 函数)。
    • 它们没有获取容器大小的引用。
    • WeakSet 不能存储基本类型数据。
    • 他们很 “弱” 地管理它们的键。也就是说,当键没有任何引用的时候可以被垃圾回收。
  • 使用 “弱” 形式时,你放弃了容易了解内部是什么或将函数应用到整个集合的能力。而你得到的是对内存泄漏和隐私的控制。

  • 建议将 if 中多个布尔值的判断放到一个函数的返回值中。

  • 尽量缩小全局变量的作用域,最好可以设计我们的API。

第8章:层次结构中的重构

  • 要构建好逻辑的层次结构,尽量隔离。
  • 构造函数经常会在原型上搞事情,所以不要它不是很好用,可以使用对象字面量和工厂函数来代替。
  • 考虑好 Is-AIs-Just-A

第9章:重构到面向对象模式

  • 状态模式 的核心是愿意将可能被认为是 “属于” 某个对象的部分移动到另一个对象中。 OOP (面向对象编程)中有一种倾向,即将层次结构放在委托对象的优先级之上。
  • 装饰器 主要表现在将特性添加到现有的接口(实例)中。
  • 外观 (对象字面量的方式来定义)看起来很简洁,坏处是不容易维护。

第10章:重构异步

  • 将 “回调地狱” 变成 流式API,这种风格叫 CPS(延续传递风格)。
  • Promise 的价值在于它们改变了接口,而这些可能就是你希望进行测试的地方。

第11章:函数式重构

  • 在 FP(声明式编程)中,我们应该试图去强调,描述一个程序应该做什么,而不是应该怎么做。
  • 纯函数的好处是幂等性,也就是作用域够小并且不能改变时,你可以总是相信同样的参数进去,返回的结果是一样的。另一个好处就是不产生副作用。
  • 柯里化、函数组合是个好想法。

希望大家都可以成为心目中的大佬!

浙ICP备2022027583号-1