关于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 相关文章推荐
js 判断 enter 事件
Feb 12 Javascript
运算符&&的三个不同层次
Apr 07 Javascript
Jquery实现由下向上展开效果的例子
Dec 08 Javascript
使用jQuery和Bootstrap实现多层、自适应模态窗口
Dec 22 Javascript
jQuery formValidator表单验证
Jan 07 Javascript
JavaScript tab选项卡插件实例代码
Feb 23 Javascript
关于cookie的初识和运用(js和jq)
Apr 07 Javascript
JS控制FileUpload的上传文件类型实例代码
Oct 07 Javascript
jquery popupDialog 使用 加载jsp页面的方法
Oct 25 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
Feb 22 Javascript
vue使用Element组件时v-for循环里的表单项验证方法
Jun 28 Javascript
Angular处理未可知异常错误的方法详解
Jan 17 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
关于IIS php调用com组件的权限问题
2012/01/11 PHP
php 文件上传实例代码
2012/04/19 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
JS滚轮事件onmousewheel使用介绍
2013/11/01 Javascript
LABjs、RequireJS、SeaJS的区别
2014/03/04 Javascript
Javascript中封装window.open解决不兼容问题
2014/09/28 Javascript
微信小程序 动态传参实例详解
2017/04/27 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
vue项目中导入swiper插件的方法
2018/01/30 Javascript
微信小程序实现弹出菜单
2018/07/19 Javascript
基于jQuery拖拽事件的封装
2020/11/29 jQuery
python实现FTP服务器服务的方法
2017/04/11 Python
用Python删除本地目录下某一时间点之前创建的所有文件的实例
2017/12/14 Python
django用户注册、登录、注销和用户扩展的示例
2018/03/19 Python
python 字符串和整数的转换方法
2018/06/25 Python
Python txt文件加入字典并查询的方法
2019/01/15 Python
Python匿名函数及应用示例
2019/04/09 Python
python set集合使用方法解析
2019/11/05 Python
TensorFlow命名空间和TensorBoard图节点实例
2020/01/23 Python
Python Numpy中数据的常用保存与读取方法
2020/04/01 Python
Python如何给你的程序做性能测试
2020/07/29 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
南非最受欢迎的时尚品牌:MRP
2016/09/18 全球购物
美国购买汽车零件网站:Buy Auto Parts
2018/04/02 全球购物
自动化专业本科毕业生求职信
2013/10/20 职场文书
大学毕业生自荐书怎么写?
2014/01/06 职场文书
英语老师推荐信
2014/02/26 职场文书
安全主题班会教案
2015/08/12 职场文书
运动会广播稿20字
2015/08/19 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书
详解如何使用Node.js实现热重载页面
2021/05/06 Javascript
php 文件上传至OSS及删除远程阿里云OSS文件
2021/07/04 PHP
redis数据一致性的实现示例
2022/03/18 Redis
Windows 64位 安装 mysql 8.0.28 图文教程
2022/04/19 MySQL