Javascript学习笔记之 对象篇(四) : for in 循环
先上范例:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo }
这里我们要注意两点,一是 for in 循环会忽略 enumerable 设置为 false 的属性。例如一个数组的 length 属性。第二是,由于 for in 会遍历整个原型链,所以当原型链过长时,会对性能造成影响。
enumerable 是个很陌生的词汇,实际上,你很难在 javascript 中发现它的影子,而它实际上也是作者从 ruby 中借鉴而来的。创建 enumerable 的目的不是为了独立使用,而是采用“混用”的方式,而 Prototype 中很多方法都混用了 enumerable,所以它可以说是 prototype 的奠基石。这里不做详细介绍,详细内容可以参考 - Enumerable。
由于我们没法改变 for in 循环本身的行为,所以我们只能采取其他方法来过滤掉那些不希望出现在循环内的属性,通过 《Javascript学习笔记之对象篇(三) : hasOwnProperty》 我们知道 hasOwnProperty 方法是可以做到这一点的。
使用 hasOwnProperty 过滤
仍然使用上个例子:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }
这是唯一正确的写法,由于我们实用了 hasOwnProperty 方法,所以这次只输出 moo。如果不适用 hasOwnProperty 方法,那么当 Object.prototype 扩展时,就会出现错误。
现在很多框架都会选择从 Object.prototype 扩展方法,所以我们使用这些框架时,如果使用没有用 hasOwnProperty 过滤的 for in 循环时就会遇到问题。
总结
建议养成 hasOwnProperty 过滤属性的好习惯,不要对运行环境做任何假设,也无论原生的原型对象是否被扩展。
相关推荐
-
JavaScript中“过于”犀利地for/in循环使用示例
Java中的增强for循环很是好用 复制代码 代码如下: for (String str : list) { System.out.println(str);//其中str直接就是集合中的元素 } 但是JavaScript中为我们提供的for/in循环已然不是这么简单了 复制代码 代码如下: var car var garage= new Array() garage[0] = "宝马" garage[1] = "奔驰" garage[2] = "宾利&q
-
javascript中的循环语句for语句深入理解
程序实现中经常要用到循环语句,其中for循环是多数语言都有的.在javascript中,for循环有几种不同的使用情况,下面就分别来讲述我的理解. 第一种:(通常情况,循环执行相关操作) 复制代码 代码如下: var objA=document.getElementsByTagName("a"); var i,max; for(i=0,max=objA.length;i<max;i++){ objA[i].onclick=function(){ alert(this.innerH
-
JavaScript运行机制之事件循环(Event Loop)详解
一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM.这决定了它只能是单线程,否则会带来很复杂的同步问题.比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线
-
JavaScript中对循环语句的优化技巧深入探讨
循环是所有编程语言中最为重要的机制之一,几乎任何拥有实际意义的计算机程序(排序.查询等)都里不开循环. 而循环也正是程序优化中非常让人头疼的一环,我们往往需要不断去优化程序的复杂度,却因循环而纠结在时间复杂度和空间复杂度之间的抉择. 在 javascript 中,有3种原生循环,for () {}, while () {}和do {} while (),其中最为常用的要数for () {}. 然而for正是 javascript 工程师们在优化程序时最容易忽略的一种循环. 我们先来回顾一下for
-
javascript闭包传参和事件的循环绑定示例探讨
今天看到一个javascript的题目,按常理循环绑定事件,但是得到的结果却不是想要的. 复制代码 代码如下: <a href="#">text</a> <br> <a href="#">link</a> <script> var as = document.getElementsByTagName('a'); for ( var i = as.length; i--; ) { as[i].on
-
javascript中for/in循环及使用技巧
JavaScript 支持不同类型的循环: for - 循环代码块一定的次数 for/in - 循环遍历对象的属性 while - 当指定的条件为 true 时循环指定的代码块 do/while - 同样当指定的条件为 true 时循环指定的代码块 1. in运算符:要求其左边的运算数是一个字符串,或可以被转换为字符串,右边的运算数是一个对象或数组.如果该运算符左边的值是右边对象的一个属性名,则返回true. 例如: var point={x:1,y:2}; //对象直接量 var has_x=
-
Javascript学习笔记之 对象篇(四) : for in 循环
先上范例: // Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo } 这里我们要注意两点,一是 for in 循环会忽略 enumerable 设置为 false 的属性.例如一个数组的 length 属性.第二是,由于 for in 会遍历整个原型链,所以当原型链过长时,会
-
Javascript 学习笔记之 对象篇(二) : 原型对象
Javascript 是唯一一个被广泛运用的原型式继承的语言,所以理解两种继承方式的差异是需要时间的. 第一个主要差异就是 Javascript 使用原型链来继承: function Foo() { this.value = 42; } Foo.prototype = { method: function() {} }; function Bar() {} 设置 Bar 的 prototype 为 Foo 的对象实例: Bar.prototype = new Foo(); Bar.prototy
-
Javascript学习笔记之 对象篇(一) : 对象的使用和属性
false.toString(); // 'false' [1, 2, 3].toString(); // '1,2,3' function Foo(){} Foo.bar = 1; Foo.bar; // 1 一个经常容易被误解的就是数字常量不能视为对象,实际上数字常量仍然可以视为对象.这是因为 Javascript 解析器在解析点操作符时而将其视为浮点数特征而犯下的错误. 2.toString(); // raises SyntaxError 实际上,我们有很多方法可以使得数字常量表现为一个
-
Javascript学习笔记之 对象篇(三) : hasOwnProperty
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {goo: undefined}; foo.bar; // 1 'bar' in foo; // true foo.hasOwnProperty('bar'); // false foo.hasOwnProperty('goo'); // true 在这里,只有 hasOwnProperty 能给出正确答案,这在遍历一个对象的属性时是非常必要的.Javascript
-
Javascript学习笔记之函数篇(四):arguments 对象
每一个 Javascript 函数都能在自己作用域内访问一个特殊的变量 - arguments.这个变量含有一个传递给函数的所有参数的列表. arguments 对象不是一个数组.尽管在语法上它跟数组有相同的地方,例如它拥有 length 属性.但它并不是从 Array.prototype 继承而来,实际上,它就是一个对象. 因此,我们不能直接对 arguments 使用一些数组的方法,例如 push, pop 或 slice 等. 所以为了使用这些方法,我们就需要将其转换为一个真正的数组. 转
-
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
函数声明 function foo() {} 函数 foo 将会在整个程序执行前被 hoist (提升),因此它在定义 foo 函数的整个 scope (作用域)中都是可用的.即使在函数定义之前调用它也没问题. foo(); // Works because foo was created before this code runs function foo() {} 因为我打算专门写篇介绍作用域的文章,所以这里就不详述了. 函数表达式 对于函数声明,函数的名称是必须的,而对于函数表达式而言则是
-
Javascript学习笔记之函数篇(五) : 构造函数
Javascript 中的构造函数与其他语言相比也是不同的.任何通过关键字 new 调用的函数都可以当做构造函数. 在构造函数体内,this 指向新创建的对象.如果构造函数体内没有显示的 return 表达式,那么我们就默认返回 this,也就是新建的对象. 复制代码 代码如下: function Foo() { this.bla = 1; } Foo.prototype.test = function() { console.log(this.bla); }; var test
-
Javascript学习笔记之 函数篇(二) : this 的工作机制
全局作用域下 this; 当在全局作用域中使用 this,它指向全局对象. 这里详细介绍下全局对象: 全局对象(Global object) 是在进入任何执行上下文之前就已经创建了的对象: 这个对象只存在一份,它的属性在程序中任何地方都可以访问,全局对象的生命周期终止于程序退出那一刻. 全局对象初始创建阶段将 Math.String.Date.parseInt 作为自身属性,等属性初始化,同样也可以有额外创建的其它对象作为属性(其可以指向到全局对象自身).例如,在 DOM 中,全局对象的 win
-
Javascript学习笔记之 函数篇(三) : 闭包和引用
Javascript 中一个最重要的特性就是闭包的使用.因为闭包的使用,当前作用域总可以访问外部的作用域.因为 Javascript 没有块级作用域,只有函数作用域,所以闭包的使用与函数是紧密相关的. 模拟私有变量 复制代码 代码如下: function Counter(start) { var count = start; return { increment: function() { count++; },
-
Javascript学习笔记之函数篇(六) : 作用域与命名空间
在之前的介绍中,我们已经知道 Javascript 没有块级作用,只有函数级作用域. 复制代码 代码如下: function test() { // a scope for(var i = 0; i < 10; i++) { // not a scope // count } console.log(i); // 10 } Javascript 中也没有显示的命名空间,这就意味着一切都定义在全局作用域中.每一次引用一个变量时,Javascript 会往上遍
随机推荐
- 简单易用的倒计时js代码
- 第8天:CSS布局入门
- ms SQL server数据库备份、压缩与SQL数据库数据处理的方法
- jQuery实现表格隔行及滑动,点击时变色的方法【测试可用】
- Asp.net实现直接在浏览器预览Word、Excel、PDF、Txt文件(附源码)
- ASP.NET学习路线(详细)
- Python下的subprocess模块的入门指引
- golang实现unicode转换为字符串string的方法
- 基于JavaScript实现的快速排序算法分析
- java获取当前时间和前一天日期(实现代码)
- 写了个XML+Tree无穷树js版
- javascript与jquery中的this关键字用法实例分析
- Linux多线程编程(二)
- java使用iterator遍历指定目录示例分享
- winform基于异步委托实现多线程摇奖器
- 克隆系统 Ghost常用参数大揭秘
- 模仿J2EE的session机制的App后端会话信息管理实例
- Android实现下拉放大图片松手自动反弹效果
- Python 保持登录状态进行接口测试的方法示例
- java 中maven pom.xml文件教程详解