关于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 相关文章推荐
监控 url fragment变化的js代码
Apr 19 Javascript
Javascript下判断是否为闰年的Datetime包
Oct 26 Javascript
用JSON做数据传输格式中的一些问题总结
Dec 21 Javascript
JavaScript弹出窗口方法汇总
Aug 12 Javascript
javascript实现一个数值加法函数
Jun 26 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
Oct 21 Javascript
AngularJS基础 ng-non-bindable 指令详细介绍
Aug 02 Javascript
javascript数据类型详解
Feb 07 Javascript
创建简单的node服务器实例(分享)
Jun 23 Javascript
Webpack优化配置缩小文件搜索范围
Dec 25 Javascript
Node.js动手撸一个静态资源服务器的方法
Mar 09 Javascript
node.js通过url读取文件
Oct 16 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目录与文件操作
2011/12/30 PHP
使用PHP求两个文件的相对路径
2013/06/20 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
php使用curl模拟浏览器表单上传文件或者图片的方法
2018/11/10 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
javascript对talbe进行动态添加、删除、验证实现代码
2012/03/29 Javascript
深入理解JavaScript系列(16) 闭包(Closures)
2012/04/12 Javascript
jQuery(非HTML5)可编辑表格实现代码
2012/12/11 Javascript
jquery中的查找parents与closest方法之间的区别
2013/12/02 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
jQuery 全选 全部选 反选 实现代码
2016/08/17 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
作为老司机使用 React 总结的 11 个经验教训
2017/04/08 Javascript
详解Javascript获取缓存和清除缓存API
2017/05/25 Javascript
bootstrap Table的一些小操作
2017/11/01 Javascript
基于Vue 2.0的模块化前端 UI 组件库小结
2017/12/21 Javascript
AngularJS使用Filter自定义过滤器控制ng-repeat去除重复功能示例
2018/04/21 Javascript
[05:40]DOTA2荣耀之路6:Wings最后进攻
2018/05/30 DOTA
Python中的魔法方法深入理解
2014/07/09 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
django轻松使用富文本编辑器CKEditor的方法
2017/03/30 Python
Python中一些深不见底的“坑”
2019/06/12 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
python 基于opencv实现图像增强
2020/12/23 Python
详解rem 适配布局
2018/10/31 HTML / CSS
俄罗斯家居用品购物网站:Евродом
2020/11/21 全球购物
高中学生干部学习的自我评价
2014/02/21 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
2014年财务部工作总结
2014/11/11 职场文书
遗嘱继承权公证书
2015/01/26 职场文书
《包身工》教学反思
2016/02/23 职场文书
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang
详解Python中__new__方法的作用
2022/03/31 Python
vue如何在data中引入图片的正确路径
2022/06/05 Vue.js