关于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拖拽并简单保存的实现代码
Nov 28 Javascript
jquery获得页面元素的坐标值实现思路及代码
Apr 15 Javascript
JavaScript函数使用的基本教程
Jun 04 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
Nov 30 Javascript
JavaScript实现打开链接页面的方式汇总
Jun 02 Javascript
浅谈JavaScript中数组的增删改查
Jun 20 Javascript
微信小程序 教程之WXSS
Oct 18 Javascript
Vue.js中用v-bind绑定class的注意事项
Dec 13 Javascript
Angular 向组件传递模板的两种方法
Feb 23 Javascript
详解react关于事件绑定this的四种方式
Mar 09 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
Sep 08 Javascript
解决Vue使用bus总线时,第一次路由跳转时数据没成功传递问题
Jul 28 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+MySQL搭建聊天室功能实例代码
2012/08/20 PHP
解析如何去掉CodeIgniter URL中的index.php
2013/06/25 PHP
PHP 文件上传后端处理实用技巧方法
2017/01/06 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
mac系统下安装多个php并自由切换的方法详解
2017/04/21 PHP
PHP number_format函数原理及实例解析
2020/07/14 PHP
htm调用JS代码
2007/03/15 Javascript
javascript 支持链式调用的异步调用框架Async.Operation
2009/08/04 Javascript
javascript function调用时的参数检测常用办法
2010/02/26 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
Bootstrap导航条的使用和理解3
2016/12/14 Javascript
js自定义瀑布流布局插件
2017/05/16 Javascript
原生js实现简单的链式操作
2017/07/04 Javascript
浅析Vue中method与computed的区别
2018/03/06 Javascript
js replace 全局替换的操作方法
2018/06/12 Javascript
小程序实现层叠卡片滑动效果
2019/08/26 Javascript
详解Nuxt.js中使用Element-UI填坑
2019/09/06 Javascript
微信小程序后端(java)开发流程的详细步骤
2019/11/13 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
2020/04/30 Javascript
vue props default Array或是Object的正确写法说明
2020/07/30 Javascript
python使用beautifulsoup从爱奇艺网抓取视频播放
2014/01/23 Python
Python获取远程文件大小的函数代码分享
2014/05/13 Python
python中for用来遍历range函数的方法
2018/06/08 Python
Python开启线程,在函数中开线程的实例
2019/02/22 Python
python实现列表的排序方法分享
2019/07/01 Python
浅析python,PyCharm,Anaconda三者之间的关系
2019/11/27 Python
CSS3教程(4):网页边框和网页文字阴影
2009/04/02 HTML / CSS
html5读取本地文件示例代码
2014/04/22 HTML / CSS
黑猩猩商店:The Chimp Store
2020/02/12 全球购物
趣味运动会广播稿
2014/09/13 职场文书
手机被没收的检讨书
2014/10/04 职场文书
2015年企业新年寄语
2014/12/08 职场文书
晚会开幕词
2015/01/28 职场文书
个人催款函范文
2015/06/24 职场文书