zoukankan      html  css  js  c++  java
  • Js整理备忘(04)——数组基础

    概念:数组(array)是一个有序的、值的集合。每个值叫做一个元素(element),每个元素在数组中都有个数字化的位置,叫做下标(index)。

    类型:数组是复合数据类型。数组实质上是一种特殊的对象,它是一个具有额外功能层的对象。例如,下面两行代码返回类型都为object

    typeof ([1,2]);

    var a=[]; typeof(a);

    特点:元素数量可以无限多,元素可以是任意类型的数据(同一数组中元素类型可以不同),被赋值的元素下标可以不连续(未定义的元素默认值为undefined)。

    1、数组的创建

    (1)使用数组直接量

    var a=[];//定义一个没有元素的数组,即空数组,数组长度为0,此时a[0]==undefined==null

    var b=[20,,,["asd",5],"qwe"];//未定义的元素默认为undefined,此时b[1]==undefined

    (2)使用Array()构造函数

    • 无参数

    var a=new Array();//创建一个没有元素的空数组

    • 传n个参数,即指定了数组前n个值,注意不要出现两个连续的逗号"," ,这一点跟数组直接量方式有区别。

    var b=new Array(20,["asd",5],"qwe");//跟数组直接量相比,这种方法似乎显得不太方便

    • 传一个数字参数

    var a=new Array(10); //创建了一个拥有10个元素的数组,即a.length==10,此时每个元素的值都是undefined

    2、数组元素的一些操作

    只记录一些注意点,需要时可查找相关资料。

    数组中无序的属性,不参与数组元素的操作。

    (1)添加新元素

    • 通过下标添加元素

    通过数组下标,可以随时给数组的任意位置添加任意类型的元素,只需要一个简单的赋值操作即可。例如:

    var arr=[];arr[10]="nihao"; //给数组中下标为10的元素(有序序列中的第11个元素)赋值,不需要关心其他位置的元素是否定义。

    可见Js中数组可以是稀疏的(sparse),数组中有效值的下标不必须连续。其中没有定义的元素默认值为undefined,Js不会给它分配内存。

    • 通过属性名添加元素

    这是数组中比较特别,也比较有趣的一点,主要是由于数组本质上是对象,所以很自然应该具备对象的所有特性。例如:

    var a=[];a["name"]="An array for test."; //给数组对象a添加了一个名为“name”的属性,属性值是一个字符串,完全符合语法。

    数组与对象的区别与联系(按照自己的理解整理,不一定准确)

    <1>数组属于对象的一种,但又高于对象。前面提过,对象中的属性名是标识符或者字符串,而数组的下标理论上应该也可以被看作数组的属性名,只不过这种属性名是用“整数值(即下标值)”表示的。这样看的话数组属于对象似乎就更好理解了。

    <2>从定义上来看,对象的属性是无序的,而数组则是有序的值的集合。但数组也是一种对象,所以自然也可以包含无序的属性,这是不是跟定义有点矛盾了呢?但是谁叫Js本来就是一种宽松的语言呢,所以也就犯不着顶真了。有时觉得Js语言很聪明,很会给自己留退路,也很贴近生活。【凡事无绝对,只有矛盾才是绝对存在的。】

    不过有一点倒不用担心,这种无序元素的存在不会影响数组的一些正常操作。例如上一个例子中,虽然给空数组a添加了一个“name”属性,但是a.length的值仍然是0。

    注:对象并没有length属性。当然length属性也不是数组特有,后面介绍的函数也有length属性,不过意义是不同的。

    <3>似乎也可以这样理解,添加了无序属性的数组,变成了这样一个对象,该对象中包含最初定义的传统意义上的数组对象,和额外添加的无序属性。而对该对象的操作,在使用下标时,仍然是直接操作原先定义的那个数组。

    (2)删除数组元素

    • delete运算符只是将一个数组元素设置成undefined值,但是元素本身仍然存在,即所有元素下标位置不变。
    • 要真正删除一个元素,需使用指定的数组方法:

    Array.shift()方法——无参,对数组本身而言总是删除掉第一个元素,返回值即为删除的元素,删除后数组下标自动迁移。

    Array.pop()方法——无参,总是删除掉最后一个元素,返回值即为删除的元素,删除后数组下标自动迁移。

    Array.splice()方法——传递两个整数参数时,表示从一个数组中删除连续下标范围的元素。

    下面数组的方法中还会具体介绍。

    (3)截断或增长数组

    数组的length属性既可以读也可以写。

    若设置的新length的值比当前数组的length值小,则数组被“截断”,该长度之外的元素都被抛弃,值也丢失。

    若设置的新length的值比当前数组的length值大,则数组被“增长”,新增位置上的值默认为undefined。

    这里列举一些例子,说明数组元素的部分操作:

    <script type="text/javascript" language="javascript">
        var b = [{ x: 1 }, 20, "abc", , ["asd", 5], true];  //b.length值为6
        delete b[1];        //将元素b[1]的值设为undefined。b应该变为[{x:1},,"abc",,["asd", 5],true]
        b[2] = undefined;   //与上句作用一样。             b应该变为[{x:1},,,,["asd", 5],true]
        b.id = "id";        //给数组对象添加一个名为"id"的无序属性。
        document.write(b.toString() + "<br/>");     //<1> 会输出id吗?
        
        b["id"] = "new value"; //<2> 可以对该添加的无序属性进行操作吗?
        b.pop();            //<3> 删除数组最后一个元素,数组length会变化吗?删除的是有序数组中的“true”,还是新增的元素id呢?
        for (p in b) {
            document.write(p + ":" + b[p]+" ; ");   //<4> 遍历数组元素,会输出id吗?
        }
        document.write("<br/>" + b.length);         //<5> 结果5还是6 ?
    </script>

    运行后,页面输出的结果如下:
    [object Object],,,,asd,5,true
    0:[object Object] ; 2:undefined ; 4:asd,5 ; id:new id ;
    5

    回答运行之前的疑问:

    综合问题<1>、<3>和<5>:第一行并没有输出id及其值。而pop()操作,并没有删除id,而是删除了有序数组中最后一个元素“true”。length的值减少了1应该是由pop()导致。

    ——由结果猜想:对b使用数组内部方法进行操作时,实际上只对其中的原始数组对象操作(即:添加的无序命名属性除外)。并且length的值不受无序属性的影响。只决定于原始的数组。

    问题<2>:看结果的第二行,id的值为“new id”,说明数组是可以对添加的无序属性进行操作的

    问题<4>:说明用遍历数组的方式(for/in)可以输出当前数组对象中所有的属性值,包括无序属性。

    3、数组的一些方法

    (1)join()方法

    ——原来的数组不变,返回“数组的所有元素组成的字符串,各元素之间默认用逗号分隔”,返回值类型为字符串(string)。

    若指定参数,则结果字符串中各数组元素之间用指定的参数(string类型)隔开,若不指定参数,则使用逗号分隔。例:

    <script language="javascript" type="text/javascript">
        var a = [1, 2, "asd", 4];
        document.write(a.join());       // 1,2,asd,4
        document.write(a.join("0"));    // 1020304
        document.write(a.join("*"));    // 1*2*asd*4
        document.write(a.toString());   // 1,2,asd,4 原数组不变
    </script>
    该方法恰好与String.split()相反,后者通过将一个字符串分割成几个片段来创建一个数组。
     

    (2)reverse()方法

    ——直接对原数组操作,返回将数组元素倒序排列后的数组。结果如下:

    var a = [1, 2, "asd", 4];
    document.write(a.reverse());    //4,asd,2,1
    document.write(a.toString());   //4,asd,2,1

    (3)sort()方法

    ——直接对原数组操作,返回排序后的数组。注意以下几点:

    • 若不指定参数,它将按照字母顺序对数组元素排序(即使数组元素全是数字 )
    var a = [33, 4, 111, 22, 234, 12];
    document.write(a.sort()); //结果:111,12,22,234,33,4
    
    • 若数组中含有未定义的元素,这些元素将被放在数组的末尾。
    • 若要将数组按照别的顺序排序,必须使用一个比较函数作为sort()方法的参数,

    例如以下将数组将按照数值大小排序:

    document.write(a.sort(
        function(a, b) {
            return a - b;//按数字升序排序: 4,12,22,33,111,234
        }
    ) );
    document.write(a.sort(
        function(a, b) {
            return b - a;//按数字降序排序: 234,111,33,22,12,4
        }
    ));

    上面的例子是将函数直接量作为sort()方法的参数的,也可以传递函数名。如下,将忽略字母大小写进行升序排列:

    function f(s1, s2) { 
        if (s1.toLowerCase() < s2.toLowerCase()) {
            return -1;
        }
        else if (s1.toLowerCase() > s2.toLowerCase()) {
            return 1;
        }
        else return 0;
    }//先定义一个比较函数f
    var str = ["agp", "AadDf", "Better"];
    document.write(str.sort(f));//结果显示:AadDf,agp,Better

    (4)slice()方法

    ——原来的数组不变,返回指定数组的一个片段(slice),或者说是子数组。注意几点:

    若只传递一个参数,则返回的数组为以参数数值为起点下标到原数组结束处的所有元素。

    若传递两个参数,则参数分别表示返回片段的起止下标位置。

    可以传递负整数,参数值-1是指数组的倒数第一个元素。(较容易理解,示例省略)

    (5)splice()方法

    ——这是插入或删除数组元素的通用方法。

    ——直接对原数组操作,原数组变成处理后的数组,返回删除掉的元素组成的数组。

    该方法可以设置多个参数:第一个参数指定位置,第二个参数指定删除的元素个数。后面还可以有任意多个参数,表示在该位置要新插入的数组元素。

    一些例子说明:

    var p, q;
    p = [1, 2, 3, 4, 5];
    q = p.splice(3);    //p=[1,2,3]; q=[4,5]
    q = p.splice(1, 2); //p=[1]; q=[2,3]
    var m, n;
    m = [1, 2, 3, 4, 5];
    n = m.splice(2, 0, 'a', 'b'); //m=[1,2,'a','b',3,4,5]; n:[]
    n = m.splice(2, 2, [1, 2], 3); //m=[1,2,[1,2],3,3,4,5]; n:['a','b']
    
    

    (6)push()、pop()、shift()、unshift()

    push()——将一个或多个新元素附加到指定数组后面。

    pop() ——直接对数组操作,删除最后一个数组元素,返回删除的值,注意,pop无参,每次只删除一个值。

    shift()——直接对数组操作,删除并返回第一个数组元素。

    unshift()——将一个或多个新元素附加到指定数组开头。

    (7)一些新增方法

    自 FireFox 1.5 起,开始支持 JavaScript 1.6 , 在 JavaScript 1.6 里,javascript 数组增加了几个非常有用的方法:indexOf、lastIndexOf、every、 filter、 forEach、 map、 some,其中前两个可以用于元素快速定位,而后面的几个则可以归为迭代(iterative)方法。

    但是,这些新方法并非所有浏览器都支持,有兴趣的话,可以参考:Javascript 1.6 数组新增方法介绍 ,逐个介绍这些方法的使用,以及针对不支持的浏览器的处理办法。

    4、类似数组的对象

    本文上面整理的“数组与对象的区别与联系”中也提到一点:数组中有length属性而对象中没有。

    猜想:那是不是说如果一开始定义的是一个对象,然后给它添加上length属性,它就可以作为数组一样处理呢?(当然它应该不可以完全变成数组,只是可以将它当作“类似数组的对象”)

    这种类似数组的对象虽然具有length属性,但是并不能调用数组的方法,因为其本质并不是数组。

    不过,可以使用遍历数组的代码来遍历这种对象。例如:

    <script language="javascript" type="text/javascript">
        var a = {};     //定义对象
        for (var i = 0; i < 10; i++) {
            a[i] = i * i;
        }
        a.length = i;   //这里很关键,因为对象本身没有length属性
        
        for (var j = 0; j < a.length; j++) {
            document.write(a[j] + ";");//结果输出:0;1;4;9;16;25;36;49;64;81;
        }    
    </script>

    分析:在给a对象添加属性时,a[i]中的 i 理论上应该会被转换为字符串处理,下图证明了这一猜想:

    1

    但是若对一个数组,可不可以使用数字字符串作为下标访问其元素呢???

    ——答案是:可以的。

  • 相关阅读:
    OK335xS-Android mkmmc-android-ubifs.sh hacking
    OK335xS-Android pack-ubi-256M.sh hacking
    OK335xS Ubuntu 12.04.1 版本 Android 开发环境搭建
    Qt Quick Hello World hacking
    Qt QML referenceexamples attached Demo hacking
    QT 5.4.1 for Android Ubuntu QtWebView Demo
    I.MX6 working note for high efficiency
    QT 5.4.1 for Android Windows环境搭建
    mkbootimg hacking
    Generate And Play A Tone In Android hacking
  • 原文地址:https://www.cnblogs.com/gppblog/p/1646226.html
Copyright © 2011-2022 走看看