js中for in 可以遍历对象或数组的显性属性,也就是说我们自己定义的属性是可以遍历的,那些原型上默认已有的属性,例如:Object.prototype.toString、Object.prototype.hasOwnProperty 是遍历不出来的。

for in 的基本规则如上,不过还有“坑”的地方需要我们注意:

1、for in循环出的值不一定是按顺序的。代码如下:

var b = {3:1,42:2,11:3}
for( var key in b ){
alert( b[key] )
}

低版本浏览器弹窗的顺序是:1、2、3。现代浏览器弹窗的顺序是1、3、2。

2、在原型上加扩展方法,会被for in 出来。代码如下:

Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
alert(key + " : "+ b[key])
}

我们手动加在原型上的方法,for in的时候会被遍历出来。一般我们遍历对象并不需要其原型的属性,所以遍历时最好Object.prototype.hasOwnProperty方法进行判断。

3、在实例中定义原型中已有的方法,浏览器for in 情况不一致。代码如下:

var b = {"name":"txj"}
b.toString = function(){ alert("I am toString") }
for( var key in b ){
alert(key + " : "+ b[key])
}

我们给b实例加了一个原型上已有的方法toString。现代浏览器能循环出toString 低版本浏览器却不能。所以给实例定属性名时,不要和原型已有的一致。

4、各浏览器循环出的属性顺序不同。代码与2中的一样:

Object.prototype.test = "I am test"
var b = {"name":"txj"}
for( var key in b ){
alert(key + " : "+ b[key])
}

现代浏览器先循环实例中的属性,再循环原型中的属性。低版本浏览器相反。

这让我想到了jQuery对$.isPlainObject()方法实现的一段代码:

// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key
for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );

它这里说如果一个对象的最后一个属性是实例自己的属性,那么所有的属性都是实例自己的属性。这对低版本浏览器来说应该是不对的。所以jquery后来又加了如下代码修复:

// Support: IE<9
// Handle iteration over inherited properties before own properties.
if ( support.ownLast ) {
for ( key in obj ) {
return hasOwn.call( obj, key );
}
}

最后想吐槽一下,一般不要在原型上加自定义方法;数组的循环一般不用for in 。哈哈!

谈谈js中for in 需要注意的地方的更多相关文章

  1. 简单谈谈js中的MVC

    MVC是什么? MVC是一种架构模式,它将应用抽象为3个部分:模型(数据).视图.控制器(分发器). 本文将用一个经典的例子todoList来展开(代码在最后). 一个事件发生的过程(通信单向流动): ...

  2. 谈谈JS中的高级函数

    博客原文地址:Claiyre的个人博客如需转载,请在文章开头注明原文地址 在JavaScript中,函数的功能十分强大.它们是第一类对象,也可以作为另一个对象的方法,还可以作为参数传入另一个函数,不仅 ...

  3. 谈谈JS中的原型

    不知道大家对JS中的原型理解的怎么样,我想如果大家对JS中的原型对象以及prototype属性十分熟悉的话对后面原型链以及继承的理解会十分的容易,这里想和大家分享自己对其的理解,请先看下面这段代码O( ...

  4. 谈谈JS中的函数节流

    好吧,一直在秋招中,都没怎么写博客了...今天赶紧来补一补才行...我发现,在面试中,讲到函数节流好像可以加分,尽管这并不是特别高深的技术,下面就聊聊吧! ^_^ 备注:以下内容部分来自<Jav ...

  5. [转] 谈谈JS中的函数节流

    函数节流的目的 从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的.例如,DOM 操作比起非DOM 交互需要更多的内存和CPU 时间.连续尝试进行过多的DOM 相关操作可能会导致浏览 ...

  6. 简单谈谈js中Promise的用法

    首先先推荐一篇博文:http://blog.csdn.net/jasonzds/article/details/53717501 这篇博文很清晰的说明了Promise的用法,这里来简单总结一下: Pr ...

  7. 初识js中的闭包

    今天看了关于js闭包方面的文章,还是有些云里雾里,对于一个菜鸟来说,学习闭包确实有一定的难度,不说别的,能够在网上找到一篇优秀的是那样的不易. 当然之所以闭包难理解,个人觉得是基础知识掌握的不牢,因为 ...

  8. 晨叔技术晨报: 你真的搞懂JS中的“值传递”和“引用传递”吗?

    晨叔周刊,每周一话题,技术天天涨. 本周的话题是JS的内存问题(加入本周话题,请点击传送门). 图 话题入口 今天的技术晨报来,就来谈谈JS中变量的,值传递和引用传递的问题.现在,对于很多的JSer来 ...

  9. JS 中如何判断 undefined 和 null

    JS 中如何判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正确的 ...

随机推荐

  1. 文件流操作(FileStream,StreamReader,StreamWriter)

    大文件拷贝: /// <summary> /// 大文件拷贝 /// </summary> /// <param name="sSource"> ...

  2. vJine 第三波 之 Lua 来袭 vJine.Lua

    vJine.Lua vJine.Lua是Lua语言的C#封装库,可实现通过C#直接运行Lua脚本并与Lua脚本交互的功能. 1. 授权: MPL2.0 相关资源: nuget:(https://www ...

  3. Sublime Text 3初体验之Package Control

    http://www.imooc.com/article/12616 下面介绍几款Sublime Text 常用Package 1.Emmit 2.JavaScript & NodeJS Sn ...

  4. String的几种初始化方法的区别

    参考了: java中String的两种初始化方法   String a; String aa = ""; String aaa = "123"; String ...

  5. ECMAScript 5.1 Edition DOC 学习笔记

    1.类型 string number object boolean null undefined symbol (es6) attention : (typeof null) 值为 'object', ...

  6. 小技巧:SystemTray中进行操作提示

    SystemTray中进行操作提示在wp中应用比较广泛,截图如下. 实现方法也十分简单 1.xaml代码中写入: shell:SystemTray.IsVisible="True" ...

  7. Mysql单实例脚本自动化安装

    安装包:mysql-5.6.31.tar.gz 已有配置文件:my.cnf *注意:本次Mysql的配置文件是在my.cnf的基础上更改得到的,my.cnf存放路径为/opt/rh/my.cnf 脚本 ...

  8. DEDECMS中,list标签和pagelist标签

    列表数据标签:dede:list {dede:list col='' titlelen='' infolen='' imgwidth='' imgheight='' orderby='' pagesi ...

  9. C语言函数参数既做出参又做入参的代表

    //使用fcntl对文件进行加锁 #include "stdio.h"#include "unistd.h"#include "fcntl.h&quo ...

  10. C#使用Zxing2.0生成二维码 带简单中心LOGO

    参考:http://www.open-open.com/lib/view/open1379214678162.html 代码:http://files.cnblogs.com/halo/%E4%BA% ...