JavaScript——for循环
for循环的理解
javascript使⽤for循环遍历数组
我们如何遍历数组元素?在javascript刚出现的时候,我们可能会这样进⾏数组遍历
for (var i = 0; index < Array.length; index++) {
console.log(Array[i]);
}
in运算符的含义代码看起来很简单对吧,但是仔细阅读代码,我们仅仅只需要取数组元素的值,却需要提前获取数组长度和声明索引变量等,当有多层循环嵌套的时候,就需要更多的索引变量,⼤⼤增加了代码的复杂度。于是乎,在ES5中就出现了for-Each⽅法来进⾏遍历
使⽤forEach遍历数组
使⽤forEach遍历数组,可以这样写
Array.forEach(function (value) {
console.log(value);
})
这段代码看起来很简单了,但是也有⼀些⼩问题,不能使⽤break语句中断循环也不能使⽤return语句返回到外层函数,当然了,使⽤for循环去遍历数组也是个不错的选择,不过,还可以⽤⼀种⽅式遍历数组,那就是for-in
for-in遍历数组
使⽤for-in遍历数组,代码如下
for (var i in Array) { // 千万别这样做
console.log(Array[i]);
}
但是这个选择建议不要使⽤,为什么呢?
在这段代码中 i的值实际上不是下标的数字,⽽是字符串"0","1","2","3",此时很可能在⽆意间进⾏字符串运算,例如 “2” + 1 == “21” ,这样会给编码过程带来很⼤的⿇烦
for-in 不仅可以遍历数组元素,还可以遍历⾃定义属性,例如,如果你的数组中有⼀个可枚举属性Array.username,循环将额外进⾏遍历⼀次,遍历到索引为‘username'的索引
for-in还有可能会随机顺序遍历数组元素总之,for-in是为普通对象量⾝定制的,你可以遍历得到字符串类型的键,因此不适⽤于数组遍历。现在我们来讲⼀个⾼⼤上的数组遍历⽅式-for-of循环
注意:for-in循环在早期的js版本中是基于in运算符的,新运算符不管某个属性是⾃⾝的还是继承的,都会返回true,这就导致⾮⾃⾝属性也会被遍历,为了解决这个问题,引⼊了可遍历概念,只有可遍历属性才会被for-in循环遍历,同时规定toString这类实例对象继承的原⽣属性是不可遍历的,从⽽保证了for-in循环的可⽤性。⽽上⾯所说的可遍历性就是指属性对象描述中的enumerable,当enumerable为false时,下⾯三个操作都取不到原⽣属性:
for..in循环
Object.keys⽅法
JSON.stringify⽅法
注意,in循环包括继承的属性,Object.keys⽅法不包括继承的属性。如果需要获取对象⾃⾝的所有属性,不管是否可遍历,可以使
⽤OwnPropertyNames⽅法。
另外,JSON.stringify⽅法会排除enumerable为false的属性,有时可以利⽤这⼀点。如果对象的 JSON 格式输出要排除某些属性,就可以把这些属性的enumerable设为false。
for-of循环
简介
⾃从引⼊ES6以来,就增加了很多新的东西,⽽for-of循环就是其中⼀种,话不多说,直接上代码看看for-of循环长什么样,其实很简单
for (var value of Array) {
console.log(value);
}
看到这⾏代码是不是觉得很眼熟,对的,长得很像for-in把,我们来探讨⼀下for-of循环的外表下到底隐藏了多少强⼤的功能吧,⾸先需要记
住以下⼏点
for-of是最简单,最直接的遍历数组元素的语法
成功的避开了for-in循环的所有缺陷
与forEach不同的是,它可以正确的相应break,continue和return语句
for-of可以⽤来⼲什么呢?
⾸先,他可以⽤来遍历对象属性,也可以⽤来遍历数据(数组中的值),不仅如此!for-of循环还可以遍历其他的集合 for-of不仅⽀持数组遍历,还⽀持⼤多数类数组对象,例如DOM NodeList for-of循环也⽀持字符串遍历,同样,也⽀持Map和Set对象遍历。举个简单的例⼦
// 基于单词数组创建⼀个set对象
var Words = new Set(words);
⽣成了⼀个Set对象之后,就可以轻松地使⽤for-of遍历它所包含的内容了。
for (var value of Words) {
console.log(value);
}
遍历Map对象与遍历Set对象稍有不同,那是因为Map⽐较特殊,它⾥⾯的数据有键值对组成,所以需要⽤解构(destructuring)来将键值对拆解为两个独⽴的变量
for (var [key, value] of BookMap) {
console.log(key + "'s phone number is: " + value);
}
解构,他是ES6新增的特性下⾯对解构进⾏⼀个简单的了解
解构
什么是解构赋值?解构赋值允许你使⽤类似数组或对象字⾯量的语法将数组和对象的属性赋给各种变量。这种赋值语法极度简洁,同时还⽐传统的属性访问⽅法更为清晰。
通常来讲,你很可能这样访问数组中的前三个元素:
var first = array[0]
var second = array[1]
var third = array[2]
如果使⽤解构赋值的特性,将会使等效的代码变得更加简洁并且可读性更⾼:
var [first, second, third] = array
以上是数组解构赋值的⼀个简单⽰例,其语法的⼀般形式为:
[ variable1, variable2, ..., variableN ] = array;
关于解构我就不⼀⼀讲述了,现在我们回到主题,for-of循环的强⼤之处,未来的JS可以使⽤⼀些新型的集合类,甚⾄会有更多的类型陆续诞⽣,⽽for-of就是为遍历所有这些集合特别设计的循环语句。 for-
of循环不⽀持普通对象,但如果你想迭代⼀个对象的属性,你可以⽤for-in 循环(这也是它的本职⼯作)或者内建⽅Object.keys()
// 向控制台输出对象的可枚举属性
for (var key of Object.keys(Object)) {
console.log(key + ": " + Object[key]);
}
内部原理
被添加到ES6的那些新特性并不是⽆章可循,⾥⾯⼤多数特性其他语⾔都在使⽤,也证明了这些特性很有⽤,就拿 for-of 语句来说,在
C++、JAVA、C# 和 Python 中都存在类似的循环语句,并且⽤于遍历这门语⾔和其标准库中的各种数据结构。与其他语⾔中的 for 和foreach 语句⼀样,for-of 要求被遍历的对象实现特定的⽅法。所有的 Array、Map 和 Set 对象都有⼀个共性,那就是他们都实现了⼀个迭代器(iterator)⽅法,那么对于其他对象呢?不着急,也可以⾃⼰实现⼀个迭代器⽅法,这就好⽐你对⼀个对象进⾏toString操作,来告知
js如何将⼀个对象转换成字符串,也可以为任意对象实现⼀个Object⽅法,来告诉js如何去遍历这个对象。看到这⾥,⼤脑⾥也许会想,[Symbol.iterator] 这个语法到底是什么⿁,是什么意思,ES 标准委员会完全可以将该⽅法命名为 iterator(),但是,现有对象中可能已经存在名为“iterator”的⽅法,这将导致代码混乱,违背了最⼤兼容性原则。所以,标准委员会引⼊了 Symbol,⽽不仅仅是⼀个字符串,来作为⽅法名。⼀个拥有⽅法的对象被认为是可遍历的(iterable)。
迭代器对象
⼀般情况下,我们不需要从0开始实现⼀个迭代器对象,现在我们来看看,迭代器具体是什么样的,就拿for-of语句来说吧,,它⾸先调⽤被遍历集合对象的⽅法,该⽅法返回⼀个迭代器对象,迭代器对象是可以拥有.next()⽅法的任何对象,然后,在 for-of 的每次循环中,都将调⽤该迭代器对象上的 .next ⽅法,看下⾯⼀个简单的迭代器对象⽣成⽅法
var Itera = {
[Symbol.iterator]: function () {
return this;
},
next: function () {
return {done: false, value: 0};
}
};
在上⾯代码中,每次调⽤.next()⽅法都返回了同⼀个结果,该结果⼀⽅⾯告知for-of语句循环还没有结束,另⼀⽅⾯告知for-of本次循环的值是0,这也就意味着上⾯⽅法是⼀个死循环,当然了,⼀个典型的迭代器绝对不会这么简单的在ES6中,迭代器通过.done和.value这两个属性来标识每次的遍历结果,这就是迭代器的设计原理现在我们知道了for-of的⼀些细节,那么我们可以简单的重写语句
for (VAR of ITERABLE) {
代码内容
}
上⾯只是⼀个语义化的实现,使⽤⼀些底层⽅法和⼏个临时变量
var iterator = ITERABLE[Symbol.iterator]();
var result = ();
while (!result.done) {
VAR = result.value;
STATEMENTS
result = ();
}
上⾯代码并没有涉及到如何调⽤.return()⽅法,我们可以添加相应的⽅法去处理。for-of 语句使⽤起来⾮常简单,但在其内部有⾮常多的细节值得我们去深⼊研究。
结束
ES6⾥⾯新增了很多很好玩⼜实⽤的特性,都值得我们去学习,for-of只是其中的⼀部分,还有更多的新特性可以去学习,今天就讲到这了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论