zoukankan      html  css  js  c++  java
  • 关于js中for in的缺陷浅析

    转自:http://www.jb51.net/article/44028.htm

    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来判断下。

  • 相关阅读:
    二分图 洛谷P2055 [ZJOI2009]假期的宿舍
    并查集 洛谷P1640 [SCOI2010]连续攻击游戏
    贪心 洛谷P2870 Best Cow Line, Gold
    贪心 NOIP2013 积木大赛
    快速幂 NOIP2013 转圈游戏
    倍增LCA NOIP2013 货车运输
    树形DP 洛谷P2014 选课
    KMP UVA1328 Period
    动态规划入门 BZOJ 1270 雷涛的小猫
    KMP POJ 2752Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/tv151579/p/4038491.html
Copyright © 2011-2022 走看看