关于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 相关文章推荐
Javascript 日期对象Date扩展方法
May 30 Javascript
javascript 计算两个整数的百分比值
Dec 26 Javascript
js去除空格的12种实用方法
Nov 08 Javascript
如何使用HTML5地理位置定位功能
Apr 27 Javascript
jfinal与bootstrap的登录跳转实战演习
Sep 22 Javascript
JQuery实现简单的图片滑动切换特效
Nov 22 Javascript
javascript计算对象长度的方法
Oct 25 Javascript
webpack项目轻松混用css module的方法
Jun 12 Javascript
详解js的视频和音频采集
Aug 09 Javascript
Vue 中如何正确引入第三方模块的方法步骤
May 05 Javascript
vue项目中在可编辑div光标位置插入内容的实现代码
Jan 07 Javascript
JS实现iframe中子父页面跨域通讯的方法分析
Mar 10 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
星际争霸 Starcraft 编年史
2020/03/14 星际争霸
为什么夜间收到的中波电台比白天多
2021/03/01 无线电
CodeIgniter配置之routes.php用法实例分析
2016/01/19 PHP
PHP+apc+ajax实现的ajax_upload上传进度条代码
2016/01/25 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
PHP十六进制颜色随机生成器功能示例
2017/07/24 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
2020/06/24 PHP
PHP 出现 http500 错误的解决方法
2021/03/09 PHP
JavaScript For Beginners(转载)
2007/01/05 Javascript
javascript 数组排序函数sort和reverse使用介绍
2013/11/21 Javascript
JS+CSS简单树形菜单实现方法
2015/09/12 Javascript
JavaScript核心语法总结(推荐)
2016/06/02 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
2017/09/02 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
ElementUI radio组件选中小改造
2019/08/12 Javascript
浅谈vue 组件中的setInterval方法和window的不同
2020/07/30 Javascript
详解JavaScript的this指向和绑定
2020/09/08 Javascript
python之super的使用小结
2018/08/13 Python
浅析PyCharm 的初始设置(知道)
2020/10/12 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
python3处理word文档实例分析
2020/12/01 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
英国第一独立滑雪板商店:The Snowboard Asylum
2020/01/16 全球购物
对于没有初始化的变量的初始值可以作怎样的假定
2014/10/12 面试题
业务经理岗位职责
2013/11/11 职场文书
女大学生自我鉴定
2013/12/09 职场文书
物流管理专业自荐信
2014/06/23 职场文书
2014县政府领导班子对照检查材料思想汇报
2014/09/25 职场文书
财务审计整改报告
2014/11/06 职场文书
先进人物事迹材料
2014/12/29 职场文书
运动会200米广播稿
2015/08/19 职场文书
银行求职信怎么写
2019/06/20 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang