Open lessfish opened 8 years ago
mark~
_.isNaN() 更新了,用的是native的isNaN方法。
@EdwardZZZ 确实,感谢指出~
isNaN有Native的
@FarmanYu 对的,edge 版本已经用 native 的函数判断了
有2点疑问:
1、isNaN
有原生的,直接使用即可,为什么前面还要判断isNumber
?这样做是为了排除那些不常见的边界情况?
2、_.isNumber(obj) && obj !== +obj;
,只有_.isNumber(obj)
为true
才会执行第二个判断,执行到第二个判断就说明一定是number
类型的,但是为什么又要把obj用+号转一次呢?
@pod4g 好问题。
首先我们明确下 underscore 中 _.isNaN 方法的作用,引用文档 http://underscorejs.org/#isNaN:
Note: this is not the same as the native isNaN function, which will also return true for many other not-number values, such as
undefined
.
也就是说,_.isNaN 如果要返回 true,必须传入一个 Number 类型。
isNaN(undefined);
=> true
_.isNaN(undefined)
=> false
这就是为什么要判断 isNumber 的原因。事实上可以看看 edge 版本的源代码:
// Is the given value `NaN`?
_.isNaN = function(obj) {
return _.isNumber(obj) && isNaN(obj);
};
这就非常清晰了,需要满足 isNumber 和 isNaN 两个条件。
话说回来,满足 isNumber 后,为什么要用 + 号转一次呢?
var a = new Number(NaN);
a !== a;
=> false
a !== +a;
=> true
很显然,我们的变量 a,调用 _.isNaN,希望返回的是 true。
事实上,_.isNaN 可能和 Number.isNaN 更接近一点。
@hanzichi 原来是这样的。谢谢!underscore
变了思路。我受原生isNaN
的影响,觉得 不是一个数字
就意味着不是一个数字
,例如,undefined
确实不是一个数字。。underscore
收窄了范围(不进行强制类型转换了)。
再次感谢楼主!
一直想提醒一下,Github不是BBS,若非有实质内容,诸如“谢谢楼主”,“感谢”这类的信息可否不要发布在issues讨论里面。
@hanzichi hey, 我想把你的這些分析, 寫成英文, 並放在自己的筆記中以供學習. 可以嗎? 鏈接: https://aleen42.gitbooks.io/personalwiki/content/Programming/JavaScript/Framework/underscore/type_inference_and_tutorials/type_inference_and_tutorials.html
@aleen42 可以,不过希望能指明出处,谢谢~
判断Dom元素的方法,如果对象里有nodeType属性呢。。。 _.isElement({nodeType:1})
@tudewutong 这确实是个问题 ...
_.isElement = function(obj) {
// 确保 obj 不是 null
// 并且 obj.nodeType === 1
return !!(obj && obj.nodeType === 1);
};
这里为什么要加两个! 呢?
@Baoyx007 强制转为布尔值,因为函数返回的是一个布尔值(虽然大对数情况下不加 !! 也问题不大,毕竟会隐式转换)
could you also explain why in .where method, .isMatch is passed in that returns a boolean. How the _.filter method functions when the predicate is a boolean? thanks!!
var = function (obj) { if (obj instanceof ) return obj; if (!(this instanceof )) return new (obj); this._wrapped = obj; }; 楼主你好,看源码,这段能给解读下吗?为何要这样写?
Why underscore
最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中。
阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及 API 设计的原理(向后兼容)。
之后楼主会写一系列的文章跟大家分享在源码阅读中学习到的知识。
欢迎围观~ (如果有兴趣,欢迎 star & watch~)您的关注是楼主继续写作的动力
类型判断
第一篇跟大家简单地聊了下为什么 underscore.js 用 void 0 代替了 undefined,意外地收到了不错的反响,有朋友私信我说以前还真不知道这回事,也有人催促我赶紧继续下一篇解读文章。今天就跟大家聊一聊 underscore.js 中一些 JavaScript 常用类型检查方法,以及一些工具类的判断方法。
我们先说个老生常谈的问题,JavaScript 中数组类型的判断方法,事实上,我在 Javascript中判断数组的正确姿势 一文中已经详细分析了各种判断方式的优缺点,并给出了正确的判断代码:
而 underscore 其实也正是这么做的:
nativeIsArray 正是 ES5 中 Array.isArray 方法,如果支持则优先调用;而 toString 变量就保存了 Object.prototype.toString。
如何判断对象?underscore 把类型为 function 和 object 的变量都算作对象,当然得除去 null。
再看 'Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error' 这些类型的判断,其实都可以用 Object.prototype.toString.call 来判断,所以写在了一起:
但是看 isArguments 方法,在 IE < 9 下对 arguments 调用 Object.prototype.toString.call,结果是 [object Object],而并非我们期望的 [object Arguments]。咋整?我们可以用该元素是否含有 callee 属性来判断,众所周时,arguments.callee 能返回当前 arguments 所在的函数。
工具类判断方法
接下来看下一些常用的工具类判断方法。
判断一个元素是否是 DOM 元素,非常简单,只需要保证它不为空,且 nodeType 属性为 1:
如何判断一个元素为 NaN?NaN 其实是属于 Number 类型,Object.prototype.toString.call(NaN) 返回的是 "[object Number]",而且 NaN 不等于本身,利用这两点即可进行判断:(2016-06-21 该实现有 BUG,详见 https://github.com/hanzichi/underscore-analysis/issues/13)
当然,underscore 还有很多其他的有用的工具类判断方法,具体可以看源码 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L1192-L1263 这部分。
如果您觉得我分享的东西对您有所帮助,请关注我的 Repo https://github.com/hanzichi/underscore-analysis