概述
<pre name="code" class="plain">
各种编程语言都有数组或者容器。对它们进行遍历,想必大家对for,foreach,iterator都有所了解。但是在同时学习了java和javascript语言的时候,看到了不同语言中对它们的不同实现与使用,下面分享一下对它们的使用心得:
1、for
for循环是最简单最基本的,任何语言都提供了其语法层次上的支持:
</pre><pre code_snippet_id="372624" snippet_file_name="blog_20140601_1_4096029" name="code" class="html">java:
int a[] = {1,2,3};
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
javascript:
var a = [1,2,3];
for(var i=0;i<a.length;i++){
console.log(a[i]);
}
这里没有什么好讲的,就是普通的for循环,这种普通循环的特点就是:
需要自己维护一个索引变量,这里就是i.
然后就是要明确知道数组的长度。
提示:for循环的一种简单优化就是事先保存要遍历对象的length,或者从后往前通过i--反过来遍历。这样的好处是不需要每次循环都访问变量,并读取其长度属性。尤其是当被遍历的是一个dom对象的时候,这种优化尤为重要,因为dom的访问开销很大。
2、foreach
foreach,很多语言也都实现了这种遍历语法,但是java和javascript中,我们平时所说的foreach可能会有些差异,让我们来看看:
java:
int a[] = {1,2,3};
for(int element: a){
System.out.println(element);
}
输出:1,2,3
javascript:
var a= [1,2,3];
for(var element in a){
console.log(element);
}
输出:0,1,2
java对foreach的语法实现是for( : ){}形式,如例子中看到,element为a中的元素。然而javascript中有一个语法实现for( in ){},很多人说它是foreach,我们姑且也说它是foreach,但是它的执行却完全不同,如例子中看到,element是a的索引,对于这个语法一会再讲。所以如果从功能相同性上来讲,javascript中的for in实际上并不是我们正常意义上理解的foreach。而事实上javascript也有foreach的实现,但是并不是实现在语法层次,而是实现为了Array对象的一个原型方法,请看:
var a = [1,2,3];
a.forEach(function(element){
console.log(element);
});
这里是通过回调函数来处理元素,element才真正是a中的每一个元素。这种方式遍历数组的特点是:
简洁方便,节省代码,不需要显示维护一个索引i,不需要知道数组的长度。所以和for相比较,如果循环中不需要用到对应元素的索引,那么用这种方式就比较好,貌似有一定优化(这个没有细研究)。实际上javascript的forEach方法是有第二个参数的,第二个参数就是对应元素的索引,而且在forEach内部肯定也是通过一个索引来访问数组的,所以对于javascript,for和foreach就没有索引上的差别了。而只是形式上和性能上的差别了。
2.1插入性的讲讲javascript的for in
实际上javascript的for in是用来遍历对象属性的,而数组也是一个特殊的对象,所以我们也可以用它来遍历数组,正确的遍历方式:
var a = [1,2,3];
for(var i in a){
console.log(a[i]);
}
输出:1,2,3
tip:这段可能提到一些js相关知识点,比如原型,属性的特性,数组对象方法等,这些不会细讲。请学习对应基础知识。这里只关注本文主题。
3、iterator
终于到了最强大的iterator,也就是迭代器。迭代器作为一种设计模式,比较之前两种方法,就不仅仅是形式上的变化和完成遍历需求了,其更重要的目的是对设计上的帮助。
首先看java:
在java中,有一个专门的Iterator类,而迭代器的使用一般是结合各类容器的。先看一个简单的例子:
List<Integet> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
a.add(3);
Iterator<Integer> aIt = a.iterator();
while(aIt.hasNext()){
System.out.println(aIt.next());
}
不过迭代器最重要的地方在于其内部迭代不必知晓被迭代的容器对象的确切类型,也就是不需要知道这个容器是ArrayList,linedList,HashSet,TreeSet或者什么,这有什么好处呢?对于代码复用,数据与操作的解耦很有帮助,
比如:
public static void display(Iterator<Integer> it){
while(it.hasNext()){
System.out.println(it.next());
}
}
public static void main (String args[]){
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
a.add(3);
LinkedList<Integer> b = new LinkedList<Integer>(a);
HashSet<Integer> c = new Hashset<Integer>(a);
display(a.iterator());
display(b.iterator());
display(c.iterator());
}
对于display方法,它所遍历的对象是不和容器相关的,所以对于a,b,c,display是可重用的。想一想如果display不用迭代器实现,它接收一个ArrayList对象,然后用for或者foreach进行遍历。那么如果你想遍历的是一个LinkedList对象,你不得不为LinedList重写,或者重载这个方法。如果又多了一个HashSet呢,又多了一个TreeSet呢……
这才是迭代器的牛逼之处。
下面我们再来看看javascript
javascript应该不存在迭代器的原生实现,一些类库中应该有。所以我们可以自己实现一个简单的迭代器,它的形式就模仿java的就可以,自己实现可控性就很强了,迭代器的实现也并不是很难,基础功能就是实现hasNext和next方法,想要添加其它的什么功能就随你喜欢了。然而javascript中,因为其弱类型性,迭代器设计上的这种作用好像不那么明显了,因为对于任何类型的对象display都是可以接受的,这样就不需要用iterator来统一接口进行接受(这可能也是没有原生迭代器的原因)。但是其实迭代器作为一种模式,其作用不仅如此,就像上文中我说的我碰到的一种情况,这应该作为设计模式进行讲解,这里先不讲。下一篇文章会讲到迭代器设计模式和js的迭代器实现。以上就是我对for,foreach和iterator的理解以及java和javascript在这方面上的差异。
最后
以上就是无限秀发为你收集整理的java和javascript的for,foreach,iterator的全部内容,希望文章能够帮你解决java和javascript的for,foreach,iterator所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复