You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 判断浏览器是否存在枚举bug,如果有,在取反操作前会返回falsevarhasEnumBug=!{toString: null}.propertyIsEnumerable('toString');// 所有需要处理的可能存在枚举问题的属性varnonEnumerableProps=['valueOf','isPrototypeOf','toString','propertyIsEnumerable','hasOwnProperty','toLocaleString'];// 处理ie9以下的一个枚举bug functioncollectNonEnumProps(obj,keys){varnonEnumIdx=nonEnumerableProps.length;varconstructor=obj.constructor;// 读取obj的原型varproto=(_.isFunction(constructor)&&constructor.prototype)||ObjProto;// 这里我有个疑问,对于constructor属性为什么要单独处理?// Constructor is a special case.varprop='constructor';if(_.has(obj,prop)&&!_.contains(keys,prop))keys.push(prop);while(nonEnumIdx--){prop=nonEnumerableProps[nonEnumIdx];// nonEnumerableProps中的属性出现在obj中,并且和原型中的同名方法不等,再者keys中不存在该属性,就添加进去if(propinobj&&obj[prop]!==proto[prop]&&!_.contains(keys,prop)){keys.push(prop);}}}
// 获取对象obj的所有的键// 与keys不同,这里包括继承来的key// Retrieve all the property names of an object._.allKeys=function(obj){if(!_.isObject(obj))return[];varkeys=[];// 直接读遍历取到的key,包括原型上的for(varkeyinobj)keys.push(key);// Ahem, IE < 9.if(hasEnumBug)collectNonEnumProps(obj,keys);// 同样处理一下有枚举问题的浏览器returnkeys;};
// Retrieve the values of an object's properties._.values=function(obj){// 用到了前面已经写好的keys函数,所以values认为获取的属性值,不包括原型varkeys=_.keys(obj);varlength=keys.length;varvalues=Array(length);for(vari=0;i<length;i++){values[i]=obj[keys[i]];}returnvalues;};
前言
underscore.js源码分析第四篇,前三篇地址分别是,如果你对这个系列感兴趣,欢迎点击watch,随时关注动态。
教你认清这8大杀手锏
那些不起眼的小工具?
(void 0)与undefined之间的小九九
原文地址
源码地址
客观别急,今天真的是要说一个bug,也许你早已知晓,也许你时常躺枪于他手,悄悄地,我们慢慢开始。
for in 遍历对象属性时存在bug
for in 遍历对象属性时存在bug
for in 遍历对象属性时存在bug
使用
for in
去遍历一个对象俺们再熟悉不过了,经常干这种事,那他到底可以遍历一个对象哪些类型的属性呢?长得帅的
还是看起来美美的
,瞎说,它能够遍历的是对象身上那些可枚举标志([[Enumerable]])为true
的属性。true
举个例子哪些属性可以被枚举
for in
并没有枚举出Object原型上的一些方法toString
也是可枚举的如何判断一个对象的属性是可枚举的
为什么obj判断toString为不可枚举属性,而obj2就是可枚举的了呢?原因很简单,obj2将
toString
重写了,而一个对象自身直接赋值的属性是可被枚举的说了这么多,接下来我们来看一下下划线中涉及到遍历的部分对象方法,come on!!!
_.has(object, key)
平时你可能经常这样去判断一个对象是否包含某个属性
但是这样做有缺陷,比如某个属性其对应的值为0,null,false,''空字符串呢?这样明明obj有以下对应的属性,却因为属性值为假而通过不了验证
所以我们可以采用下划线中的这种方式
源码
_.keys(object)
使用示例
源码
collectNonEnumProps函数分析
简单地说就是如果对象将其原型上的类似
toString
的方法覆盖了的话,那么我们认为toString
就是可枚举的了,但是在ie9以下的浏览器中还是认为是不可以枚举的,又是万恶的ie源码
代码看起来并不复杂,但是有一个小疑问,对于constructor属性为什么要单独处理呢?各个看官,如果知晓,请教我啊
_.allKeys(object)
举个简单的例子说明
接下来看下源码是怎么干的
源码
可以看到和_.keys的唯一的不同就在于遍历obj的时候有没有用
hasOwnProperty
去判断_.values()
使用案例
源码
_.invert(object)
使用案例
注意哟,如果对象中有些属性值是相等的,那么翻转过来的对象其key取最后一个
源码
_.functions(object)
源码
结尾
The text was updated successfully, but these errors were encountered: