Javascript中的for in循环和hasOwnProperty结合使用


Posted in Javascript onJune 05, 2013

与in操作符相比,for in 在循环对象的属性时也会遍历原型链,for in 不会读取不可枚举属性,如数组的length属性。 小结 当检测某个对象是否拥有某个属性时,hasOwnProperty 是唯一可以完成这一任务的方法,在 for in 循环时,建议增加 hasOwnProperty 进行判断,可以有效避免扩展本地原型而引起的错误。

与in操作符相比,for in 在循环对象的属性时也会遍历原型链,for in 不会读取不可枚举属性,如数组的length属性。

// 扩展 Object.prototype 
Object.prototype.bar = 1; 
var foo = {moo: 2}; 
for(var i in foo) { 
console.log(i); // 输出 bar 和 moo 
}

我们不可能改变 for in 循环的行为,当需要对循环体内某些属性进行过滤时,可以利用Object.prototype的hasOwnProperty方法来完成。

提示:因为 for in 循环总是遍历整个原型链,所以当遍历多继承的对象时效率较低。

使用 hasOwnProperty 进行过滤

// 仍旧针对上例的foo对象 
for (var i in foo) { 
if (foo.hasOwnProperty(i)) { 
console.log(i); 
} 
}

例子中因为使用了hasOwnProperty,最终输出moo;如果忽略 hasOwnProperty ,代码将会输出非预期结果,因为本地原型(如Object.prototype)已经被扩展了。

Prototype框架就是扩展Javascript原始对象的一个类库,并被广泛使用,其缺点也很明显,当框架引入后,如果不使用 hasOwnProperty 进行过滤判断,输出结果保证不是你想要的。

最佳实践

推荐在 for in 时,总是使用 hasOwnProperty 进行判断,没人可以保证运行的代码环境是否被污染过。

hasOwnProperty
为了检查某个对象是否拥有不在原型链上的自定义属性,就有必要用到 hasOwnProperty 方法,任何一个对象都具有该方法,它继承自 Object.prototype。

提示:我们无法完全检测某个属性是否是undefined,因为属性有可能存在,但其值为undefined。hasOwnProperty 是Javascript中唯一一个可以处理对象属性而不遍历原型链的方法。

// 扩展 Object.prototype 
Object.prototype.bar = 1; 
var foo = {goo: undefined}; foo.bar; // 1 
'bar' in foo; // true 
foo.hasOwnProperty('bar'); // false 
foo.hasOwnProperty('goo'); // true

只有 hasOwnProperty 给出了正确的预期结果,当遍历对象的属性时这是很有必要的,没有其它办法来排除定义在对象原型链上的属性。

hasOwnProperty 作为属性

Javascript 并没有保护 hasOwnProperty 为关键字或保留字,因此,如果某个对象拥有同名的属性,就有必要利用扩展的 hasOwnProperty 来获取正确结果。

var foo = { 
hasOwnProperty: function() { 
return false; 
}, 
bar: 'Here be dragons' 
}; 
foo.hasOwnProperty('bar'); // 总是返回 false 
// 使用另一个 hasOwnProperty 并将 this 设置为 foo 来调用它 
{}.hasOwnProperty.call(foo, 'bar'); // true

小结
当检测某个对象是否拥有某个属性时,hasOwnProperty 是唯一可以完成这一任务的方法,在 for in 循环时,建议增加 hasOwnProperty 进行判断,可以有效避免扩展本地原型而引起的错误。

Javascript 相关文章推荐
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
Apr 24 Javascript
js点击页面其它地方将某个显示的DIV隐藏
Jul 12 Javascript
基于jquery自定义图片热区效果
Jul 21 Javascript
js Dialog 实践分享
Oct 22 Javascript
批量修改标签css样式以input标签为例
Jul 31 Javascript
深入分析下javascript中的[]()+!
Jul 07 Javascript
jQuery实现网页抖动的菜单抖动效果
Aug 07 Javascript
Angular.js之作用域scope'@','=','&'实例详解
Feb 28 Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
Mar 03 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
js最简单的双向绑定实例讲解
Jan 02 Javascript
jQuery实现获取多选框的值示例
Feb 07 jQuery
理解JAVASCRIPT中hasOwnProperty()的作用
Jun 05 #Javascript
jquery 面包屑导航 具体实现
Jun 05 #Javascript
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
Jun 05 #Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
Jun 05 #Javascript
JQuery AJAX 中文乱码问题解决
Jun 05 #Javascript
Javascript自定义排序 node运行 实例
Jun 05 #Javascript
jquery 文本上下无缝滚动,鼠标放上去就停止 小例子
Jun 05 #Javascript
You might like
提升PHP执行速度全攻略(下)
2006/10/09 PHP
初探PHP5
2006/10/09 PHP
php文章内容分页并生成相应的htm静态页面代码
2010/06/07 PHP
PHP实现的一致性哈希算法完整实例
2015/11/14 PHP
PHP目录与文件操作技巧总结(创建,删除,遍历,读写,修改等)
2016/09/11 PHP
PHP 实现公历日期与农历日期的互转换
2017/09/13 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
js 图片轮播(5张图片)
2008/12/30 Javascript
JS获取农历日期具体实例
2013/11/14 Javascript
javascript强制点击广告的方法
2015/02/06 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
2015/08/24 Javascript
深入理解关于javascript中apply()和call()方法的区别
2016/04/12 Javascript
分享JS数组求和与求最大值的方法
2016/08/11 Javascript
JS实现六位字符密码输入器功能
2016/08/19 Javascript
JavaScript实现的CRC32函数示例
2016/11/23 Javascript
微信小程序 图片加载(本地,网路)实例详解
2017/03/10 Javascript
微信小程序中使用Promise进行异步流程处理的实例详解
2017/08/17 Javascript
JavaScript惰性求值的一种实现方法示例
2019/01/11 Javascript
详解jQuery如何实现模糊搜索
2019/05/10 jQuery
[53:03]Optic vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
详解从Django Rest Framework响应中删除空字段
2019/01/11 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
python中round函数保留两位小数的方法
2020/12/04 Python
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
英国汽车零件购物网站:GSF Car Parts
2019/05/23 全球购物
几道Java和数据库的面试题
2013/05/30 面试题
入党申请人的自我鉴定
2013/12/01 职场文书
英语专业学生个人求职信范文
2014/01/06 职场文书
企业演讲比赛主持词
2014/03/18 职场文书
保险公司早会主持词
2014/03/22 职场文书
教师职位说明书
2014/07/29 职场文书
舞蹈社团活动总结
2015/05/07 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
Django操作cookie的实现
2021/05/26 Python
redis 存储对象的方法对比分析
2021/08/02 Redis