JavaScrip实现计数器的多种方法
总结一下 JavaScript 实现计数器的几种方法,对于写出高性能代码有一定的帮助,同时也包含一些蛇皮操作。
普通写法
1 | var counter = 0; |
创建一个全局变量counter
,每次调用countUp()
都会使counter
的值+ 1,但是我们都知道无论是用何种语言写代码,都应该尽量使用少的全局变量,于是就有了下面这种经典写法。
使用闭包
1 | const countUp = (() => { |
这种写法能使用更少的全局变量,但闭包终归有闭包的缺点,它不会被垃圾回收机制处理,同时也不能像上一种写法那样重置counter
,于是就有了下面这种写法。
使用函数属性
1 | const countUp = () => { |
在 JavaScript 中函数是一种特殊的对象,既然是对象,那他自然也有属性,我们定义一个函数来操作它的counter
属性。这种写法很好的解决了上面三个问题:
- 解决闭包的内存占用
- 可以重置
counter
- 尽量少的全局变量
如果你会TypeScript
,那么通过下面这个例子你能更好的理解函数属性。
1 | interface CountUp { |
上面这段代码定义了一个函数接口,这个函数拥有 0 个参数,返回值是一个number
类型的值,并且有counter
属性。
让我们看看最后一种写法,这种写法没有任何优势,甚至是大材小用的写法。
Generator
1 | const counter = (function* Counter() { |
在这里,我们使用了一个无限迭代器来实现,通过使用counter.next()
来手动使迭代器迭代,个人认为这种写法比使用闭包的开销还要大,用作计数器实在是大材小用了。迭代器在 ES6 之前就被实现了,在 ES6 中才正式成为规范,它在 JavaScript 的作用通常是用来构建异步函数(async/await)。
虽然最后这种写法没有什么实质性的作用,但对于理解迭代器还是有帮助的,另外,有些厂笔试就喜欢出这种花里胡哨的题。