-
Notifications
You must be signed in to change notification settings - Fork 642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
内部方法 createAssigner 详解 #4
Comments
再请教一个问题,.each和.map中,为什么前者的迭代函数是iteratee = optimizeCb(iteratee, context);而后者的却是iteratee = cb(iteratee, context); |
好问题,这点我也十分诧异,个人觉得两者作用相同,可以互换。类似的还有 |
@zhoucumt |
可否采用 undefinedOnly === void 0 来判断,而非 arguments.length |
如果在严格模式,这里用的arguments还行吗? |
@ooooevan 不行。 |
@sqfbeijing 为什么不行,可以的啊,严格模式只是淘汰了arguments.callee 和 arguments.caller |
@anotherleon caller 并不在 arguments对象上的 |
Why underscore
最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中。
阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及 API 设计的原理(向后兼容)。
之后楼主会写一系列的文章跟大家分享在源码阅读中学习到的知识。
欢迎围观~ (如果有兴趣,欢迎 star & watch~)您的关注是楼主继续写作的动力
createAssigner
(PS:本文有点水,没多少干货,主要想跟大家分享下这里的闭包)
今天要跟大家聊的是 underscore 源码中一个重要的内部方法,createAssigner。
这个方法是用来干嘛的呢?该方法涉及的 api 包括 _.extend & _.extendOwn & _.defaults,那么这三个 api 又是用来干嘛的呢?ok,先简单介绍下这三个 api 的用处。
首先思考这样一个场景,有 a,b 两个对象,将 b 所有的键值对都添加到 a 上面去,返回 a,如何写这个方法?恩,应该不难,刷刷刷写下如下代码:
我擦,这么少,这是真的吗?是真的,除了没有兼容 IE < 9 下某些 key 不能被 for ... in 枚举到的 bug(这个可以参考 前文)。你不禁开始怀疑人生,讲这个有毛的意义?
事实上,_.extend 大概就是用来干上面 extend 函数的事情的;而 _.extendOwn 则只会取 b 对象的 own properties,大同小异; _.defaults 呢?跟 _.extend 类似,但是如果 key 相同,后面的不会覆盖前面的,取第一次出现某 key 的 value,为 key-value 键值对。除此之外,三个方法都能接受 >= 1 个参数,以 .extend 为例,.extend(a, b, c) 将会将 b,c 两个对象的键值对分别覆盖到 a 上。
那么问题来了,如何设计这三个用途相似的 api?我们来看看 underscore 是怎么做的。
我们完整地看下带注释的 createAssigner 函数:
函数返回函数,并且返回的函数引用了外面的一个变量,这不正是经典的闭包?因为变量的个数可以 >=1,于是我们用 arguments 去获取变量。当变量个数为 1,或者第一个参数是 null 时,这时我们不需要做任何 "extend",直接返回第一个参数。之后,我们便可以用 arguments 枚举除去第一个参数外的其他参数,将它们的键值对覆盖到第一个参数对象上,具体可以看我的源码注释。
The text was updated successfully, but these errors were encountered: