这个题目略微浅显,但却不易讲明白。如果我告诉你,我们不能以任何代码保证可以有序遍历出一个数组的所有元素,你肯定会反驳我,因为使用for明明就可以啊!但其实不是。

一、为什么FOR不能保证遍历所有?

代码0:

var arr1 :Array = ["as3", "expert", "programming"];arr1.name = "sban";for(var j:int=0; j{trace(arr1[j]);}

代码0仅能遍历出3个元素,原因在于动态添加的元素name是在Object上添加的,因Array是动态对象所以可以这样行码,但它并不受Array管理,也并未被统计在length之中。

二、ARRAY对象是如何设计的?

Array继承于Object,是动态对象,使用动态属性直接在Object上存储数据。当下标与元素的对应关系发生变化时,受到影响的属性名称会全部重写。Array在内部维护一个length属性,元素的改变不受制于length,length因元素而改变。(注:此观点乃sban个人推测,非官方,接爱请审慎)

据上一段,我们可以推断:

1,设有数组arr1,arr1[0]元素的属性名称为“0”,使用arr1[0]访问数组元素与使用arr1[“0”]的效果是相同的

2,对于大数组的添加元素操作,push的效率远远高于unshift

3,数组既可以使用for遍历,也可以使用for in与for each in遍历,后两者是所有Object都具有的遍历方法。

4,可以无视数组的定义长度,跳跃指定元素的下标。

让我们验证一下我们的推断:

代码1:

var arr1 :Array = ["as3", "expert", "programming"];trace(arr1[0], arr1["0"]);//as3 as3

代码2:

var arr1 :Array = [], arr2 :Array = [];

var t1:Number, t2:Number;t1 = new Date().getTime();for(var j:Number=0;j<100000;j++){arr1.push(j);}t2 = new Date().getTime();trace("push耗约:", t2-t1);//push耗约: 35t1 = new Date().getTime();for(var j:Number=0;j<100000;j++)//这个数值如果太大,比如5千万,你会发现你的电脑根本就无法完成它{arr2.unshift(j);}t2 = new Date().getTime();trace("unshift循环耗约:", t2-t1);//unshift循环耗约: 7881

代码3://遍历一个5千万的数组,用三种方法遍历及速度对比

var t1:Number, t2:Number;var arr1 :Array = [];for(var j:Number=0;j<50000000;j++)//for遍历{arr1.push(j);}t1 = new Date().getTime();for each(var p:* in arr1)//for each in遍历{var i1:* = p;}t2 = new Date().getTime();trace("for each in耗约:", t2-t1);//for each in耗约: 8891t1 = new Date().getTime();for(var p:* in arr1)//for遍历{var i2:* = arr1[p];}t2 = new Date().getTime();trace("for in耗约:", t2-t1);//for in耗约: 9861t1 = new Date().getTime();var n:Number = arr1.length;for(var k:Number=0; k<n; k++){var i3:* = arr1[k];}t2 = new Date().getTime();trace("for耗约:", t2-t1);//for耗约: 9720

代码4://无视数组既有长度,跳跃指定元素的下标

var arr :Array = new Array(1);arr['2'] = "sban";//arr[2] = "sban",使用数字与字符串作下标,效率是相同的,AS3内部会作必要的类型转化trace("length:", arr.length);for(var j:int=0; j<arr.length; j++){trace(arr[j]);}/* length: 3 undefined undefined sban */

这个白痴的特性让人很失望!C语言的数组从来都是先分配大小的,不充许越界赋值。AS3的Array的length变得没有任何实际意义,它既不能限制数组元素的随意添加,也不能正确的彰显数组到底有多少元素。

三、为什么ADOBE要把ARRAY设计为动态对象?

在AS3中,其它基本数据类型如String,Number均是非动态对象,为什么Array要被设计为动态对象?Adobe为什么要充许外部代码在Array上动态创建属性?Array作为数组,竟然可以拥有自己的动态属性,貌似这是一个很不合理的设计。

作者并非在Adobe工作,并不了解如此设计的真正玄机。sban看过一份Flash Player v4 v++源码,但Array是Flash Player 9之后才出现的,里面并没有关于Array的相关代码。

sban推测正则表达式的命名组功能是促使Adobe把Array设计为动态对象的主要原因之一。

代码4:

var s :String = “as expert programming by sban.“;var arr : Array = /by (?P\w+)/i.exec(s);trace(arr.name);//sbantrace(arr is Array);//true

对于正则的exec方法,如何保证在返回数组对象的同时,该对象又具有用户指定的动态属性,把Array设计为动态对象是最简洁的方法之一,并且这与AS3是一门纯面向对象语言的思想并不违悖。

四、总结

遍历一个数组有三种方法:

1,for遍历

2,for in遍历

3,for each in遍历

如果要保证有序遍历,只能使用方法一,但不能保证遍历所有;如果要保证遍历所有,可以使用方法2或3,但不能保证有序。三种方法遍历小数组的效率没有差别,遍历大数组时略有差别。

五、建议

存储无序元素集合,使用Object优于Array。

Optimus 2008/4/1 北京

本文采用署名-非商业性使用-相同方式共享协议,属于AS3-Expert的一部分,转载请注明作者 及出处,非商业。

如果您是Flash/AS3技术的爱好者,请加入AS3高级技术群:44985308,70782097。如果你是Flash/AS3方面的专家,请加入AS3专家群(71057902),申请验证请附上作品链接或博客地址。

为什么for不能有序遍历数组的所有元素?(Array的设计原理)的更多相关文章

  1. 遍历数组中的元素(含es6方法)

    假如有这样一个数组.arr = [12,34,45,46,36,58,36,59],现在要遍历该数组. 方法1:以前我们可能会这样做: for(var i=0;i<arr.length;i++) ...

  2. 用C#中的键值对遍历数组或字符串元素的次数

    代码如下: string strs = "ad6la4ss42d6s3"; Dictionary<char, int> dic = new Dictionary< ...

  3. Struts2的OGNL遍历数组、List、简单的Map

    一.简介 <s:iterator />可以遍历 数据栈里面的任何数组,集合等等 在使用这个标签的时候有三个属性值得我们关注      1. value属性:可选的属性,value属性是指一 ...

  4. IT兄弟连 Java语法教程 数组 使用foreach循环遍历数组元素

    从JDK5之后,Java提供了一种更简单的循环:foreach循环,也叫作增强for循环,这种循环遍历数组和集合更加简洁.使用foreach循环遍历数组和集合元素时,无需获得数组或集合的长度,无需根据 ...

  5. PHP数组——定义,类型,遍历数组,数组函数

    1.定义 $attr=array();                            //标准定义方式 $attr=[1,2]; $attr[0]="hello";     ...

  6. 转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中

    转:http://www.itmian4.com/thread-6504-1-1.html 最小区间原题 k个有序的数组,找到最小的区间范围使得这k个数组中,每个数组至少有一个数字在这个区间范围内.比 ...

  7. [leetcode]26. Remove Duplicates from Sorted Array有序数组去重(单个元素只出现一次)

    Given a sorted array nums, remove the duplicates in-place such that each element appear only once an ...

  8. [LeetCode] 34. Find First and Last Position of Element in Sorted Array 在有序数组中查找元素的第一个和最后一个位置

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  9. LeetCode 88. 合并两个有序数组(Merge Sorted Array)

    题目描述 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m ...

随机推荐

  1. 百度地图API的调用

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...

  2. UVa 10539 (筛素数、二分查找) Almost Prime Numbers

    题意: 求正整数L和U之间有多少个整数x满足形如x=pk 这种形式,其中p为素数,k>1 分析: 首先筛出1e6内的素数,枚举每个素数求出1e12内所有满足条件的数,然后排序. 对于L和U,二分 ...

  3. JQuery安全分析

    JQuery安全分析: JQuery的风险均来源于对输入的数据没有进行有效性检验.客户端的Javascript需要检验:来源于服务器的数据.来源于当前页面的用户输入,服务器端需要检验来源于用户端的数据 ...

  4. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]PrI.6.1

    Given a basis $U=(u_1,\cdots,u_n)$ not necessarily orthonormal, in $\scrH$, how would you compute th ...

  5. Servlet3.0学习总结(一)——使用注解标注Servlet

    一.Servlet3.0介绍 Servlet3.0是Java EE6规范的一部分,Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述 ...

  6. hive内部表与外部表区别

    1.在Hive里面创建一个表: hive> create table wyp(id int,    > name string,    > age int,    > tele ...

  7. 安装mysql-5.7.9-winx64

    1.mysql-5.7.9-winx64.zip下载 官方网站下载地址:http://dev.mysql.com/downloads/mysql/5.7.html 2.解压到D:\MySqlDataB ...

  8. nyoj 236 心急的C小加

    心急的C小加 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的 ...

  9. iOS7自定义statusbar和navigationbar的若干问题

    当然有许多问题是这篇文章中没有提到的,按照文章的方法进行设置,你可能会遇到以下问题: 1.navigationbar的背景图片自定义以后,statusbar虽然和navigationbar共用了背景图 ...

  10. Countly在andoid和vps集成使用,开源的统计分析sdk

    这几天项目需要,简单研究了一下countly,说实话完全满足项目需要,比umeng这类产品干净多了. Countly Mobile Analytics 下面就讲一下android 集成的过程,以及 服 ...