互联网时代,稀缺的不是知识,而是整合知识的方式。
工作十多年来,我认识了很多专业的前端小伙伴,我知道大家都能够在信息爆炸的碎片化时代,找到海量的 JavaScript 知识。也正是如此,许多小伙伴对自己自学成才总是抱有一丝希望。
只有实践之后才发现,对于很多人来说,坐拥如此多的资源,可如何掌握好 JavaScript 始终是一个困扰。即使看了多本名书,具备多年工作经验,也查阅了大量的网络资源,可依然学不好它。
例如:许多人无法准确理解引用数据类型,无法感知到它在内存中的特性会给我们的工作带来哪些帮助与困扰。
许多人也无法准确理解闭包,他们能够大概表达出来闭包的定义,却不知道闭包在项目中是如何帮助我们完成大量的工作,以及如何利用闭包的特性来帮助我们实现各种高级运用。甚至有少量的人还觉得闭包有害,认为闭包是 JavaScript 的设计缺陷。
许多人无法理解事件循环,没有认知到事件循环的重要意义,无法将事件循环与线程结合起来理解,不知道如何借助事件循环的机制达到性能优化的目的。
甚至很多人不理解函数,无法感知到函数声明与函数执行的区别,没有想过函数声明与函数执行在内存中的不同表现,无法很好的利用函数完成一些难度看上去偏高的目标。
最最最关键的是,许多人无法在自学的过程中培养出来完整、健全的抽象思维,让自己的水平始终在一个很普通的层面徘徊,无法突破瓶颈。
很显然,这些海量的知识,找到它们,并不等于学会它们
这些知识的相关文章,在网上并不难获取。只要学习过前端一段时间,大家多多少少都对它们有一定的理解,然而,也正是这些知识,阻碍了你更进一步。大多数前端人,都缺乏知识整合的方式。
因此,如果有这么一本书,他介绍的所有内容,都依托于一种行之有效的知识整合方式,那么这本书,在当今时代,一定是一本非常稀缺的好书。
这本书,就是《JavaScript 核心进阶》
知识的整合过程,也是构建知识体系的过程。
知识体系,就是把分散且看上去独立的概念或者观点,加以整合,形成具有一定关联性的知识系统. 和许多人认知中完全不同的是,完整、健全的知识体系,它是一个网状结构。
事实上,有许多小伙伴并没有意识到自己应该去构建自己的知识体系。除此之外,还有许多学习习惯非常好的道友,将知识体系整合成为一种树状结构,或者线性结构。最后发现用处并不是那么大。
在这个信息爆炸的互联网时代,我们接触到的所有知识,都是凌乱而分散的。将这些知识,通过自己的理解和消化,整合成为属于我们自己的网状结构知识体系,非常困难。
这非常考验一个人的个人学习能力,而大多数人,不具备这样的能力。
于是,许多人自学前端,常常对掌握到的知识似懂非懂。你会有一种不知道这些知识学过来有什么用的困惑。这样的困惑,会让你怀疑自己是否真的掌握了这个知识。时间一久,你甚至会完全忘记它。你无法感知到自己的进步。
许多人也常常因为自己会遗忘所学的知识而苦恼
这正是因为,大家没有或者不知道如何去建立属于自己的知识体系,你没办法找到基础知识和实践之间的关联性。所以你感知不到这些知识存在的价值。你也无法辨别哪些知识是可以忘记,哪些知识是核心要点。
用一个案例来说明这个结论。
我在很早之前,遇到了一个性能上的难题:仓库里有大量的商品,上亿件。需求是要计算出来所有商品的成本总价. 实现这个功能非常简单,每次计算时,只需要把所有商品的成本单价加起来,就是成本总价了。假设我们实现了一个 api,名为 getTotalPrice
,那么有如下伪代码
10// 注意,这只是伪代码20function getTotalPrice() {30// 1. 遍历数据库,查出所有的商品项及其单价40const products = db.merchandise.get();5060// 然后,遍历products「上亿项数据」,将单价 price 相加,得出结果70let total = 08090// 循环,上亿项单价相加10products.forEach(mer => {11total += mer.price;12})1314return total15}
问题就在于,仓库中的商品数量是随时变化的,每天都有大量的商品入库出库,也就意味着,商品的成本总价在不停的变化之中,与此同时,每天会有许多的用户会有查看商品成本总价的需求,如果这样的用户特别多的话,我们刚才定义的 getTotalPrice 方法就可能会在短时间内需要执行很多次。不停的重复计算在性能上的影响非常大,于是这种方案就变得不可取,那应该怎么办?
后来,我从 JavaScript 数组的 length 字段中找到了灵感。
我们先来了解一下关于 length 字段的基础知识。
数组提供了一个字段,length,用以访问数组的长度。这里我们要思考一个问题,首先,数组肯定是可以被改变的,我们可以调用 push 或者 pop 等方法来改变数组项的个数。可是为什么数组没有像我们刚才那样,提供一个 length() 方法去计算数组的长度,而是直接只提供了一个可以直接访问的 length 属性,而且这个 length 属性居然还能随时反应出正确的数组长度?
很显然,一定是做了额外的处理。
这个额外处理其实很简单,我们只需要在数组初始化时,使用 length 字段记录一次数组的长度。当数组改变「删除/新增」时,对应的去修改 length 的值就可以了。这样我们就能够随时访问到数组正确的 length,而不需要每次访问时,还要去调用一个函数计算一次。
同样的道理,对于仓库里商品的成本总价的管理,我们在仓库管理初始时,记录一次成本总价,以后每次入库,就在之前总价的基础上,加上本次入库的成本,每次出库,在之前的总价基础上,减去出库商品的成本,这样,我们就可以不用任何计算,直接得到仓库的成本总价。完美的解决了大量计算的性能问题。
一个看上去非常复杂的应用性能问题,而且还是后端数据库的解决方案,居然从最基础 JavaScript 数组的 length 属性上找到了灵感。
简直不可思议。
这就是知识体系的威力。他能够让我们拥有更强的问题解决能力。没有完善的知识体系,我想破脑袋,也不可能从最基础的 length 字段中找到解决方案。
除此之外,知识体系能够让你的学习能力得到巨大的提升。
至于为什么,这里把悬念留在后续的章节中,大家自行感受。
知识体系,能够帮助你不断佐证你所学的知识是否正确。我们在网上学到的许多知识,没有经历过权威认证,也许只是某个博主的个人所见,因此常常我们吸收到的知识会有所偏差。
例如一个重要的知识点,闭包。
许多人在这个点上出现严重的认知偏差。他们认为,闭包会造成内存泄漏,于是我们应该在实践中避免使用它,他们认为闭包是有害的。
而实际情况却是,我们很多实践场景,都在利用闭包达到我们想要的目的。闭包可以说是无处不在。
因为缺乏建立知识体系的思考过程,我们没有把闭包的基础理论,与实践结合起来理解,于是这个错误的认知,可能会伴随我们非常久的一段时间。而知识体系的完善,会帮助我们快速纠正我们的错误。
知识体系的建立过程,是对知识融汇贯通的过程。也是不断审视自己的认知是否正确的过程。我们要在知识与知识之间,理论与理论之间,理论与实践之间,建立可靠的联系。
而在 JavaScript 这一个细分方向,如何建立知识体系,《JavaScript 核心进阶》用一整本书超过 80 篇文章告诉我们答案。你值得一试!
世界上没有那么多天才,成功的背后,都是正确的学习方法和不懈的努力。
正确的学习方法,由此书来告诉你,。而你,只需要负责努力,祝愿大家都能取得事业上的成功。