关于js中for in的缺陷浅析


Posted in Javascript onDecember 02, 2013

for in 语句用来列举对象的属性(成员),如下

var obj = { name:"jack",
      getName:function(){return this.name}
};
//输出name,getName    
for(var atr in obj) {
    alert(atr);
}

注意了吗,没有输出obj的toString,valueOf等内置属性(或称内置成员,隐藏属性和预定义属性)。即for in用来列举对象的显示成员(自定义成员)。

如果重写了内置属性呢,下面就重写obj的toString

var obj = {name:"jack",
      getName:function(){return this.name},
      toString:function(){return "I'm jack."}
}
for(var atr in obj) {
    alert(atr);
}

会输出什么呢?
1、IE6/7/8 下和没有重写toString一样,仍然只输出name,getName
2、IE9/Firefox/Chrome/Opera/Safari下则输出name,getName,toString

如果给内置原型添加属性/方法,那么for in时也是可遍历的

Object.prototype.clone = function() {}
var obj = {
    name: 'jack',
    age: 33
}
// name, age, clone
for (var n in obj) {
    alert(n)
}

给Object.prototype添加了方法clone,for in时所有浏览器都显示了clone。

这或许还没什么,因为一般不建议去扩展内置构造器的原型,这也是Prototype.js走向没落的原因之一。jQuery和Underscore没有扩展自原型,前者在jQuery对象上做文章,后者索性将所有方法都挂在下划线上。

但有时我们为了兼容ES5或后续版本,会在不支持ES5的浏览器上(IE6/7/8)去扩展内置构造器的原型,这时for in在各浏览器中就不同了。如下

if (!Function.prototype.bind) {
    Function.prototype.bind = function(scope) {
        var fn = this
        return function () {
            fn.apply(scope, arguments)
        }
    }
}
function greet(name) {  
    alert(this.greet + ', ' + name)
}
for (var n in greet) {
    alert(n)
}

IE6/7/8输出了bind,其它浏览器则无。因为现代浏览器中bind是原生支持的,for in不到,IE6/7/8则是给Function.prototype添加了bind。

总结下:在跨浏览器的设计中,我们不能依赖于for in来获取对象的成员名称,一般使用hasOwnProperty来判断下。

Javascript 相关文章推荐
JQuery与JS里submit()的区别示例介绍
Feb 17 Javascript
javascript实现的右下角弹窗实例
Apr 24 Javascript
JavaScript实现表格点击排序的方法
May 11 Javascript
Bootstrap布局组件应用实例讲解
Feb 17 Javascript
javascript基础语法——全面理解变量和标识符
Jun 02 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
Jan 18 Javascript
jQuery Validate 校验多个相同name的方法
May 18 jQuery
angularJS利用ng-repeat遍历二维数组的实例代码
Jun 03 Javascript
Javascript中this关键字指向问题的测试与详解
Aug 11 Javascript
vue3.0 CLI - 2.5 - 了解组件的三维
Sep 14 Javascript
脚手架vue-cli工程webpack的基本用法详解
Sep 29 Javascript
JavaScript键盘事件常见用法实例分析
Jan 03 Javascript
js验证整数加保留小数点的简单实例
Dec 02 #Javascript
ExtJs中gridpanel分组后组名排序实例代码
Dec 02 #Javascript
javascript操作html控件实例(javascript添加html)
Dec 02 #Javascript
解析Javascript中大括号“{}”的多义性
Dec 02 #Javascript
解析JavaScript中点号“.”的多义性
Dec 02 #Javascript
解析JavaScript中的不可见数据类型
Dec 02 #Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
Dec 02 #Javascript
You might like
PHP扩展模块memcached长连接使用方法分析
2014/12/24 PHP
PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 如何解决
2016/04/17 PHP
PHP代码重构方法漫谈
2018/04/17 PHP
Javascript查询DBpedia小应用实例学习
2013/03/07 Javascript
获取offsetTop和offsetLeft值的js代码(兼容)
2013/04/16 Javascript
深入领悟JavaScript中的面向对象
2013/11/18 Javascript
用Javascript获取页面元素的具体位置
2013/12/09 Javascript
JQuery解析HTML、JSON和XML实例详解
2014/03/29 Javascript
常见浏览器多长时间会提示“脚本运行时间过长”总结
2014/04/29 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
JavaScript整除运算函数ceil和floor的区别分析
2015/04/14 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
JavaScript弹窗基础篇
2016/04/27 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
JS 中使用Promise 实现红绿灯实例代码(demo)
2017/10/20 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
vue+axios+mock.js环境搭建的方法步骤
2018/08/28 Javascript
js for终止循环 跳出多层循环
2018/10/04 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
2018/12/03 Javascript
vuex存储token示例
2019/11/11 Javascript
javascript实现页面的实时时钟显示示例
2020/08/06 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
[01:32]DOTA2次级联赛——首支职业女子战队选拔赛全记录
2014/10/23 DOTA
[00:53]2015国际邀请赛 中国区预选赛一触即发
2015/05/14 DOTA
Python下载懒人图库JavaScript特效
2015/05/28 Python
Python实现给文件添加内容及得到文件信息的方法
2015/05/28 Python
flask的orm框架SQLAlchemy查询实现解析
2019/12/12 Python
python识别验证码的思路及解决方案
2020/09/13 Python
Shein英国:女性时尚网上商店
2019/04/10 全球购物
加油口号大全
2014/06/13 职场文书
创先争优标语
2014/06/27 职场文书
优秀高中学生评语
2014/12/30 职场文书
小学二年级数学教学计划
2015/01/20 职场文书
办公室个人总结
2015/02/28 职场文书
金榜题名主持词
2015/07/02 职场文书