禁止使用for in 遍历对象

for in 对数组遍历的一个潜在bug是:如果有人在数组原型prototype添加了方法,或者引入了第三方js库,库中对数组原型进行了扩展,那么,for in 遍历数组时将会把这些原型方法也遍历出来,而for var 这种数组遍历并不会遍历出原型方法

举例

var x=[1];

for(var s in x){
     alert(s);
};

====>输出:0

var x=[1];

Array.prototype.toJson = 'xxx';
for(var s in x){
       alert(s);
};

===>输出:0,toJson

若使用for var遍历

var x=[1];

for(var i =0;i < x.length;i++){
       alert(i);
};

====>输出:0

var x=[1];

Array.prototype.toJson = 'xxx';
for(var i =0;i < x.length;i++){
     alert(i);
};

====>输出:0

由此可见for in遍历数组会出现遍历出原型方法的bug

如果坚持想用for in遍历数组,可以考虑用ECMAScript5中的defineProperty方法来给数组原型上扩展,不过:1:defineProperty方法由于是ES5的,所以不支持IE9以下的浏览器 2:必须确保所有人都用这个方法来给数组进行扩展,要不遍历就会出现问题

关于defineProperty:

这个新方法很厉害了,vue.js和avalon.js 都是通过它实现双向绑定的,所以在这里有必要介绍一下

事例:

var a= {}

Object.defineProperty(a,"b",{
     value:123
})

console.log(a.b);//123

这个方法接收三个参数

第一个:目标对象

第二个:需要定义的属性或者方法名

第三个:目标属性所拥有的特性(descriptor)

这里主要介绍下第三个参数


value: 属性的值

writable: true(属性的值可以重写),false(属性值不能重写,只能读)

configurable: 总开关,如果为false, 就不能再设置他的(value,writable,configurable)

enumerable: 是否能在for in循环中遍历出来或者在Object.keys中列举出来。

get: 下面详解

set: 下面详解

知识点1:

如果未对writable,configurable,enumerable进行设置,会自动默认为false的初始值

知识点2:configurable

var a= {}

Object.defineProperty(a,"b",{
configurable:false
})

Object.defineProperty(a,"b",{
     configurable:true
})

//error: Uncaught TypeError: Cannot redefine property: b

就会报错了。。注意上面讲的默认值。。。如果第一次不设置它会帮你设置为false。。所以。。第二次。再设置他会报错

知识点3:writable

知识点4:enumerable

这个是和我们上面介绍的for in 遍历数组有关的解决方案

enumerable设置为fasle,将会禁止枚举在defineProperty中定义的方法

set 和 get

在 descriptor 中不能 同时设置访问器 (get 和 set) 和 wriable 或 value,否则会错,就是说想用(get 和 set),就不能用(wriable 或 value中的任何一个)

var a= {}

Object.defineProperty(a,"b",{
set:function(newValue){
     console.log("你要赋值给我,我的新值是"+newValue)
},
get:function(){
     console.log("你取我的值")
     return 2 //注意这里,我硬编码返回2
}
})

a.b = 1 //打印 你要赋值给我,我的新值是1
console.log(a.b)    //打印 你取我的值

//打印 2 注意这里,和我的硬编码相同的

简单来说,, 这个 “b” 赋值 或者 取值的时候会分别触发 set 和 get 对应的函数

除了通过defineProperty,还有一种方法可以避免遍历出原型链方法:hasOwnProperty

可以用 hasOwnProperty 来确定这个属性名是该对象的成员还是来自于原型链,如果对象拥有独有的属性,它将返回true,
hasOwnProperty 方法不会检查原型链;

var obj = {
    name: 'wang',
    age: 21,
    getAge: function(){ },
    getName: function(){}
}
for(var i in obj){
    if( obj.hasOwnProperty(i) ){
        console.log(i)
    }
}

这样,将会过滤掉原型链中的方法和属性

虽然可以通过这两种方法避免遍历出原型链方法,但是还是强烈建议不要使用for in 去遍历数组!!

写完收工!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 2,585评论 9 22
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,401评论 3 12
  • 一簇迎春 迎来了一个春天 在时光中悄然盛开 不问花开几许 只道浅笑安然 三月的风 吹醒了一片绿的繁盛 梦想着像他们...
    人类灵魂男工程师阅读 360评论 0 2
  • 公司内部有这样一句话:所有人都渴望有文档,所有人都不喜欢写文档。深有体会深受其害。 文档是沉淀,是历史经验的总结,...
    黑土卡卡西阅读 244评论 1 2
  • 利用SDWebImage下载图片的原因 近期项目中有一个关于开屏广告加的需求变更。需要客户端将一段时间内的开屏广告...
    Leafly阅读 7,828评论 0 11