chechengpeng

类的复杂度和函数式编程– Kent C. Dodds – Medium

chechengpeng · 2017-06-19翻译 · 99阅读 原文链接

什么时候使用类,什么时候不使用,怎么替代它,为什么替代它

Obligatory semi-to-not-related header image via: https://unsplash.com/photos/sMQiL_2v4vs

当涉及到应用计划持续维护的时候,我们都希望有易维护的简单代码。我们也经常争论如何实现它。在这篇博客中,我将讨论我如何看待函数,对象和类,刚好也符合这个争论。

一个类

让我们看看一个类的例子来说明我的观点:

我们通过构造函数实例化声明了一个Person类,它拥有一些属性和方法。如果我们从 Chrome 的控制台打印出Person对象,它看起来像这样:

proto上拥有方法的 Person 实例

这里真正值得注意的地方是,这个person的大部分属性都在prototype上(在屏幕上以_proto_显示)而不是person实例上。这是非常重要的,因为如果我们有一万个person实例,他们能够在同样的方法上共享引用而不是有一万个那些方法的拷贝。

现在我想关注的是想要理解这段代码,你需要需要学习多少概念并且那些概念有多么复杂。

  • 对象:相当基础。绝对的入门级。它们不会增加复杂度。

  • 函数(和闭包): 这也相当的基础。闭包的确增加了一点复杂度(并且如果你不小心,它能引发一些问题 ), 但是不学习它们,你真的无法在 JavaScript 语言走得更远些 (这里可以学到更多).

  • 一个函数或者方法的this关键字:JavaScript 中非常重要的概念。

我的观点是this学起来比较困难并且给代码增加了不必要的复杂度

this关键字

这里是 MDN 关于this的介绍

JavaScript 中函数的this关键字跟其他语言有点不同。并且在严格模式和非严格模式下也有些不同。

大多数情况下,this的值取决于被调用的函数。执行过程中,不能被重新赋值,并且每次函数调用的时候它都可能不一样。ES5 提供了bind方法来绑定一个函数的this值而不用在意函数调用的方式,并且ES2015提供了箭头函数,它的this的作用域是词法作用域(this的值就是当前函数的上下文)。

也许没那么复杂,但这个隐含的关系的确比对象和闭包复杂一点。你不可能避免使用对象和闭包,但我相信大多数情况你能避免使用类和this

这有一个因使用this出错的例子(故意的):

核心问题是因为使用this你的函数因为各种各样的引用变得混乱不堪。

想要一个更真实的例子,你可在 React ⚛️ 中寻找。如果你已经使用了 React 一段时间,你可能已经遇到了我之前遇到的错误:

当你点击一个按钮的时候,你会看到: Uncaught TypeError: Cannot read property 'setState' of null at increment

这都是因为this的缘故,当我们执行onClick时,它没有调用我们的increment函数,因为this绑定在了我们组件的实例上。有一些方法可以修正它 (观看免费视频教程 egghead.io video 💻 )。

事实上你不得不考虑this增加了你的认知负荷,最好避免使用它。

如何避免 this

如果this增加了很多复杂度,我们如何在不添加更复杂代码的基础上避免它。替代面向对象的方法,我们试试函数式的方法如何?如果我们使用纯函数看起来会是这样:

用这种方法,我们不会用到this。我们无需考虑它。最终,它也很容易理解。只是函数和对象。基本上没有状态,你只需要注意这些函数,这种感觉很棒!person对象只是数据,所以更容易思考:

person3 对象只有问候和名字

函数式编程的另一个优势是很容易进行单元测试。你可以简单的调用函数并断言它的输出。在这之前,你无需设定任何状态。这是一个非常方便的特性。

注意,只要它“足够快”,函数式编程可以让代码更容易理解。尽管执行速度不是重点,在特定场景下你可使用特定的方式来获得更好的性能表现(例如用===来检查对象)。通常,使用函数式编程的瓶颈是它让你的应用变慢

成本和收益

class的使用并不坏,它的确有它的使用场景。如果你真的有一些 “hot” code 并且已经成为你应用的瓶颈,这时用class真的可以加快速度。但 99% 的时候,情况并非如此。我不认为classthis增加的复杂度在大部分情况下是值得的(我们甚至没有使用原型继承)。我也有需要使用class来获得更好的性能的时候。我只在 React 组件上使用它们,因为如果你使用状态或者生命周期方法你必须使用它们(未来可能不会)

结论

在 JavaScript 中类(和原型)有它们的使用场景。但它们是一种优化。它们没能让你的代码更加简单,反而更加复杂。所以最好把你的关注点集中在不仅学起来简单而且也容易理解的:函数和对象上。

再见朋友们!

相关文章