lessfish
lessfish
# 概述 也是好久没更新 [源码解读](https://github.com/hanzichi/underscore-analysis),看着房价蹭蹭暴涨,心里也是五味杂陈,对未来充满恐惧和迷茫 ...(敢问一句你们上岸了吗) 言归正传,今天要介绍的是 underscore 中两个重要的方法,函数节流和函数去抖。**这篇文章不会涉及具体的代码实现**(关于代码实现请期待下文),会从零开始介绍函数节流和函数去抖的概念,辨析应用场景。为什么我对这两个方法情有独钟要花大篇幅去介绍?因为就是它们带我入了「underscore 源码解读」的坑(详见 [一次发现underscore源码bug的经历以及对学术界『拿来主义』的思考](http://www.cnblogs.com/zichi/p/5331426.html))。 函数节流和去抖的出现场景,一般都伴随着客户端 DOM 的事件监听。举个例子,实现一个原生的拖拽功能(不能用 H5 Drag&Drop API),需要一路监听 mousemove 事件,在回调中获取元素当前位置,然后重置 dom 的位置(样式改变)。如果我们不加以控制,每移动一定像素而触发的回调数量是会非常惊人的,回调中又伴随着 DOM 操作,继而引发浏览器的重排与重绘,性能差的浏览器可能就会直接假死,这样的用户体验是非常糟糕的。**我们需要做的是降低触发回调的频率**,比如让它 500ms 触发一次,或者 200ms,甚至 100ms,这个阈值不能太大,太大了拖拽就会失真,也不能太小,太小了低版本浏览器可能就会假死,这样的解决方案就是函数节流,英文名字叫「throttle」。函数节流的核心是,**让一个函数不要执行得太频繁,减少一些过快的调用来节流。** 说完函数节流,再看它的好基友函数去抖(debounce)。思考这样一个场景,对于浏览器窗口,每做一次 resize 操作,发送一个请求,很显然,我们需要监听 resize...
# 前言 终于可以开始 Collection Functions 部分了。 可能有的童鞋是第一次看楼主的系列文章,这里再做下简单的介绍。楼主在阅读 [underscore.js](https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js) 源码的时候,学到了很多,同时觉得有些知识点可以独立出来,写成文章与大家分享,而本文正是其中之一(完整的系列请猛戳 )。之前楼主已经和大家分享了 Object 和 Array 的扩展方法中一些有意思的知识点,今天开始解读 Collection 部分。 看完 Collection Functions 部分的源码,首先迫不及待想跟大家分享的正是本文主题 —— 数组乱序。**这是一道经典的前端面试题,给你一个数组,将其打乱,返回新的数组,即为数组乱序,也称为洗牌问题。** 一个好的方案需要具备两个条件,一是正确性,毋庸置疑,这是必须的,二是高效性,在确保正确的前提下,如何将复杂度降到最小,是我们需要思考的。 # splice 几年前楼主还真碰到过洗牌问题,还真的是 "洗牌"。当时是用 cocos2d-js(那时还叫 cocos2d-html5)做牌类游戏,发牌前毫无疑问需要洗牌。 当时我是这样做的。每次...
# Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 [underscore.js 源码解读](https://github.com/hanzichi/underscore-analysis) 放在了我的 2016 计划中。 阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的...
自从进入七月以来,我的 [underscore 源码解读系列](https://github.com/hanzichi/underscore-analysis) 更新缓慢,再这样下去,今年更完的目标似乎要落空,赶紧写一篇压压惊。 [前文](https://github.com/hanzichi/underscore-analysis/issues/18) 跟大家简单介绍了下 ES5 中的 bind 方法以及使用场景(没读过的同学建议先看看),毕竟 bind 是 ES5 的东西,低版本 IE 不支持。今天就根据 underscore 的实现,来聊一聊如何实现一个 bind 的 polyfill。 之前在 [ECMAScript 5(ES5) 中 bind 方法简介备忘](http://www.cnblogs.com/zichi/p/4357023.html) 一文中,给出了一个 "穷人版" 的...
# Why underscore 最近开始看 underscore.js 源码,并将 [underscore.js 源码解读](https://github.com/hanzichi/underscore-analysis) 放在了我的 2016 计划中。 阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及...
[前文](https://github.com/hanzichi/underscore-analysis/issues/20) 我们对 JavaScript 中的函数节流和函数去抖的概念和应用场景进行了简单的了解,本文我们来深入探究下函数去抖的实现。(不懂函数去抖概念的建议看下前文 [JavaScript 函数节流和函数去抖应用场景辨析 ](https://github.com/hanzichi/underscore-analysis/issues/20)) 我们以 scroll 事件为例,探究如何实现滚动一次窗口打印一个 _hello world_ 字符串。 如果不对其进行节流或者去抖控制: ``` javascript window.onscroll = function() { console.log('hello world'); }; ``` 这样每滚动一次,实际上会打印 N 多个 _hello world_。函数去抖背后的基本思想是指,某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。 《高程三》给出了最简洁最经典的去抖代码(书中说是节流,实则为去抖),调用如下:...
# 前言 终于,楼主的「Underscore 源码解读系列」[underscore-analysis](https://github.com/hanzichi/underscore-analysis) 即将进入尾声,关注下 [timeline](https://github.com/hanzichi/underscore-analysis#articles源码分析过程中的产物) 会发现楼主最近加快了解读速度。十一月,多事之秋,最近好多事情搞的楼主心力憔悴,身心俱疲,也想尽快把这个系列完结掉,也好了却一件心事。 本文预计是解读系列的倒数第二篇,最后一篇那么显然就是大总结了。楼主的 Underscore 系列解读完整版地址 # 常规调用 之前写的文章,关注点大多在具体的方法,具体的知识细节,也有读者留言建议楼主讲讲整体架构,这是必须会讲的,只是楼主把它安排在了最后,也就是本文,因为楼主觉得不掌握整体架构对于具体方法的理解也是没有大的问题的。 Underscore 大多数时候的调用形式为 `_.funcName(xx, xx)`,这也是 [文档中](http://underscorejs.org/) 的调用方式。 ```javascript _.each([1, 2, 3], alert); ``` 最简单的实现方式,我们可以把 `_` 看做一个简单的对象: ```javascript var...
# Why underscore 最近开始看 underscore.js 源码,并将 [underscore.js 源码解读](https://github.com/hanzichi/underscore-analysis) 放在了我的 2016 计划中。 阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及...
[斐波那契数列](https://en.wikipedia.org/wiki/Fibonacci_number) 应该都很熟悉,如何能够快速求得斐波那契数列中某项的值呢? 一个很显然的方法是正向地叠加求解: ``` javascript "use strict"; const N = 1000; let fibonacciNumber = []; for (let i = 0; i < 1000; i++) { if (i < 2) fibonacciNumber[i]...
# Throttle [上文](https://github.com/hanzichi/underscore-analysis/issues/21) 我们聊了聊函数去抖(debounce),去抖的作用简单说是 **使连续的函数执行降低到一次**(通常情况下此函数为 DOM 事件的回调函数),核心实现也非常简单,重复添加定时器即可(具体可以参考 [上文](https://github.com/hanzichi/underscore-analysis/issues/21))。本文我们聊聊函数节流(throttle)。 简单的说,函数节流能使得连续的函数执行,变为 **固定时间段** 间断地执行。 还是以 scroll 事件为例,如果不加以节流控制: ``` javascript window.onscroll = function() { console.log('hello world'); }; ``` 轻轻滚动下窗口,控制台打印了 N 多个 _hello world_ 字符串。如果...