关于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脚本性能优化注意事项
Nov 18 Javascript
JavaScript版DateAdd和DateDiff函数代码
Mar 01 Javascript
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
May 07 Javascript
jQuery实现浮动层随浏览器滚动条滚动的方法
Sep 22 Javascript
第一次接触神奇的前端框架vue.js
Dec 01 Javascript
jquery uploadify如何取消已上传成功文件
Feb 08 Javascript
关于Bootstrap按钮组件消除黄框的方法
May 19 Javascript
微信小程序--组件(swiper)详细介绍
Jun 13 Javascript
vue路由前进后退动画效果的实现代码
Dec 10 Javascript
JavaScript深入V8引擎以及编写优化代码的5个技巧
Jun 24 Javascript
Vue中fragment.js使用方法小结
Feb 17 Javascript
Vue Cli3 打包配置并自动忽略console.log语句的方法
Apr 23 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+curl 发送图片处理代码分享
2015/07/09 PHP
PHP实现的各类hash算法长度及性能测试实例
2017/08/27 PHP
PHP接口类(interface)的定义、特点和应用示例
2020/05/18 PHP
niceTitle 基于jquery的超链接提示插件
2010/05/31 Javascript
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
在AngularJS中使用AJAX的方法
2015/06/17 Javascript
详细解读JavaScript编程中的Promise使用
2015/07/27 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
2017/08/22 Javascript
基于Vue中点击组件外关闭组件的实现方法
2018/03/06 Javascript
vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定
2018/09/14 Javascript
关于vue v-for循环解决img标签的src动态绑定问题
2018/09/18 Javascript
JavaScript中常用的简洁高级技巧总结
2019/03/10 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
2019/09/05 Javascript
vue npm install 安装某个指定的版本操作
2020/08/11 Javascript
[55:35]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第二场 1月22日
2021/03/11 DOTA
python对字典进行排序实例
2014/09/25 Python
python自动格式化json文件的方法
2015/03/11 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
2017/07/06 Python
基于tensorflow加载部分层的方法
2018/07/26 Python
解决pycharm工程启动卡住没反应的问题
2019/01/19 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
2019/08/02 Python
python3 中时间戳、时间、日期的转换和加减操作
2020/07/14 Python
Jupyter Notebook添加代码自动补全功能的实现
2021/01/07 Python
Html5之webcoekt播放JPEG图片流
2020/09/22 HTML / CSS
美国女士内衣在线折扣商店:One Hanes Place
2019/03/24 全球购物
欧缇丽加拿大官方网站:Caudalie加拿大
2019/07/18 全球购物
巴西葡萄酒商店:Divvino
2020/02/22 全球购物
英语专业推荐信
2013/11/16 职场文书
教师实习自我鉴定
2013/12/14 职场文书
高中生家长寄语大全
2014/04/03 职场文书
2014年征兵标语
2014/06/20 职场文书
小学六一儿童节活动开幕词
2016/03/04 职场文书
react如何快速设置文件路径别名
2021/04/28 Javascript
Docker下安装Oracle19c
2022/04/13 Servers