zoukankan      html  css  js  c++  java
  • javascript中的数组扩展(一)

     javascript中的数组扩展(一)

    随着学习的深入,发现需要学习的关于数组的内容也越来越多,后面将会慢慢归纳,有的是对前面的强化,有些则是关于前面的补充。

    一、数组的本质
        数组是按照次序排列的一组值,本质上,数组是一种特殊的对象
                console.log(typeof[1,2,3]);//object
        数组是对象但是对象不是数组
                var arr = ['a','b','c','d','e'];
                console.log(Array.isArray(arr));//true
                console.log(Array.isArray([]));//true
                console.log(Array.isArray({}));//false,空的对象不是数组
        数组的特性体现在,它的键名是按次序排列的一组整数。由于数组成员的键名是固定的,因此数组不用为每个元素指定键名,而对象的每个成员都要指定键名。
                var aa = ['a','b','c'];
                console.log(Object.keys(aa));//0,1,2
                var obj = {
                    name1:'a',
                    name2:'b',
                    name3:'c'
                };
        数组是对象的特殊形式。在javascript中规定对象的键名一律为字符串,所以数组的键名也为字符串。
                var o = {
                    1:'one',
                    2:'two',
                }
                console.log(o[1]);//one
        在数组中:(非字符串的键名会被转为字符串,然户将其作为属性名来使用)
                var a = ['a','b','c'];
                console.log(a['0']);//a
                console.log(a[1]);//a
        但是在数组中要区分数组的索引和对象的属性名:所有的索引都是属性名,但只有在(0~2的32次方-2)之间的整数属性名才是索引
        当属组的属性不是(0~2的32次方-2)之间的整数时,只是数组的属性名,其明显特征是不改变数组数组长度
        注意:单独的数值不能作为标识符,数组的成员只能用方括号法表示
                var a = [1,2,3]    ;
                console.log(a[0]);//0
                console.log(a.0);//Uncaught SyntaxError: Unexpected number
        下面通过例子来区别索引和属性名
                var a = [1,2,3]    ;
                a[-1.23]=true;//属性名
                console.log(a.length);//3
                a[10] = 11;//索引
                console.log(a.length);//11
                a['abc'] = 'foodoir';//属性名
                console.log(a.length);//11


    二、在谈到数组的本质的时候,我们不得不提数组检测的几种方法:            
            【typeof】   
                var arr = [1,2,3];
                console.log(typeof arr);//object,这个方法能很好的证明数组是对象
            【instanceof】
                var arr = [1,2,3];
                console.log(arr instanceof Array);//true
                var str = 'abc';
                console.log(str instanceof Array);//false
                //扩充
                var str = 'abc';
                str[0] = 1;
                str[1] = 2;
                str[2] = 3;
                console.log(str[1]);//b
                console.log(str.length);//3
                console.log(str instanceof Array);//false        
                var str = [];
                str[0] = 1;
                str[1] = 2;
                str[2] = 3;
                console.log(str[1]);//2
                console.log(str.length);//3
                console.log(str instanceof Array);//true
            【toString】
                var arr = [1,2,3];
                console.log(Object.prototype.toString.call(arr) === '[object Array]');//true
            【valueof()】

        方法返回数组本身
                var a = [1,2,3];
                console.log(a.valueOf());//1,2,3
                console.log(a.valueOf() instanceof Array);//true

     后来ECMAScript5新增了【Array.isArray()】方法。这个方法的目的最终是确定某个值到底是不是数组,而不管他是在哪个全局执行环境中创建的。这个方法的使用如下:

        if(Array.isArray(value)){
            //对数组执行某些操作
        }

    三、关于数组的长度
       通用公式:数组长度 = 最大索引 + 1,再次强调:delete操作并不该变数组的长度
     关于数组长度的深度剖析
        1、当索引大于现有数组长度时,length属性的值将设置为索引值+1
                var a = [1,2,3];
                console.log(a.length);//3
                a[10] = 11;
                console.log(a.length);//11
        2、当length属性的设置小于当前长度时,将当前索引值大于设置的数组长度的元素从数组中删除
                var a = [1,2,3,4,5];
                a.length = 3;
                console.log(a);//1,2,3
                a.length = 0;
                console.log(a);//''
                a.length = 10;
                console.log(a);//,,,,,,,,,,
                console.log(a[3]);//undefined
        3、将数组的长度设为大于当前的长度,实际上并没有想数组中添加新元素,只是在数组的尾部创建了一个空的区域(见上)
        4、将数组的length值设为不合法的值,我们来看结果
                [].length = -1;//Uncaught RangeError: Invalid array length
                [].length = Math.pow(2,32);//Uncaught RangeError: Invalid array length
                [].length = 'abc';//Uncaught RangeError: Invalid array length
        5、那么问题来了,我们如何设置数组的长度不可修改呢?
            我们可以通过前面学习对象时的相关知识来解决
                var arr = [1,2,3];
                Object.defineProperty(arr,'length',{
                    writable:false,
                });
                console.log(arr.length);//3
                arr[4] = 4;
                console.log(arr.length);//3
                console.log(arr)//1,2,3  说明设置不可修改length属性成功了

    四、前面介绍了遍历数组的三种方法:for、for/in、forEach,接下来我们针对这三种方法进行一下扩展
        for()循环
            当索引连续时,可以用for循环遍历
                var arr = ['a','b','c',123];
                for(var i = 0 ; i<arr.length;i++){
                    console.log(arr[i]);//a,b,c,123
                }
            补充:当索引连续时,也可以用while循环遍历数组
                var a = [1,2,3,4];
                var i = 0;
                while(i<a.length){
                    console.log(a[i]);//1,2,3
                    i++;
                }
                var j = a.length;
                while(j--){
                    console.log(a[j]);//3,2,1
                }
            但是如数组为稀疏数组时,仍要使用for循环怎么办?
            此时应该给for循环增加一些条件
                var a = [1,,,,5,6];
                for(var i=0;i<a.length;i++){
                    if(!(i in a)){
                        //console.log(typeof i);//number,注意:此时的返回值为number!!!
                        console.log(a[i]);//undefined
                    }
                }
            前面是我自己踏进去的个坑,下面才是正确的解法,比较这二者的区别
                var a = [1,,,,5,6];
                for(var i=0;i<a.length;i++){
                    if(!(i in a)) continue;
                    //console.log(typeof i);//number,注意:此时的返回值为number!!!
                    console.log(a[i]);//1,5,6
                }
        for/in循环
            从前面可以看出,在面对稀疏数组时,我们用for/in循环的话会方便很多
                var a = [1,,,,5,6];
                for(var i in a){
                    console.log(a[i]);//1,5,6
                }
            由于for/in循环能够枚举继承的属性名,如添加到Array.prototype中的方法。由于这个原因,在数组上不应该使用for/in循环,除非使用额外的检测方法来过滤掉不想要的属性
                var a = [1,,,4];
                a.b = 'b';
                a.c = -5;
                a.d = 7.8
                for(var i in a){
                    console.log(a[i]);//1,4,b,-5,7.8
                }
            我们可以通过加判定条件来跳过不是非负整数的i
                var a = [1,,,4];
                a.b = 'b';
                a.c = -5;
                a.d = 7.8
                for(var i in a){
                    //console.log(typeof i);//String,注意:在前面用for循环中的for/in循环中typeof的返回值为number
                    if(String(Math.floor(Math.abs(Number(i))))!==i) continue;
                    console.log(a[i]);//1,4
                }
            下面我们通过前面对象的方法中的hasOwnProperty()函数来获取不是继承下来的属性
                var arr1 = [];
                arr1[1] = 'x';
                arr1[22] = 'y';
                arr1[333] = 'z';
                for(var i in arr1){
                    console.log(arr1[i]);//x,y,z
                }//这种方法遍历的是继承下来的属性,若不想遍历继承下来的属性可以用hasOwnProperty()函数
                for(var i in arr1){
                    if(arr1.hasOwnProperty(i)){
                        console.log(arr1[i]);//x,y,z
                    }
                }//这种方法遍历的不是继承下来的属性
        我们还可以通过forEach()方法来遍历数组
            语法:Array.forEach(function(value[,index[,array]]){函数体})
                var arr2 = [1,2,3,4,5,6];
                方法一:
                arr2.forEach(function(x){
                    console.log(x);
                });1,2,3,4,5,6
                方法二:
                function Test(element,index,array){
                    console.log('要处理的数组为:'+array);
                    console.log('索引:'+index+'--值为:'+element);
                }
                arr2.forEach(Test);

    五、类数组:拥有length属性和对应非负整数属性的对象叫类数组
                var obj = {};
                obj[0] = 'a';
                obj[1] = 'b';
                console.log(obj);//Object {0: "a", 1: "b"}
                console.log(obj.length);//undefined
                但是将{}换成[],这样是不是就很熟悉了
                var arr = [];
                arr[0] = 'a';
                arr[1] = 'b';
                console.log(arr);//["a", "b"]
                console.log(arr.length);//2
                前面那个带有{}的就是类数组,我们可以通过下面的例子来进一步了解它
                var a = {};
                var i = 0;
                while(i<10){
                    a[i]=i*i;
                    i++;
                }
                a.length = i;
                var total = 0;
                for(var j=0;j<a.length;j++){
                    total += a[j];
                }
                console.log(total);//285
                有三个常见的类数组对象:arguments对象,DOM方法,字符串
                arguments对象
                function args(){
                    return arguments;
                }
                var arrayLike = args('a','b');
                console.log(arrayLike[0]);//a
                console.log(arrayLike.length);//2
                console.log(arrayLike instanceof Array);//false
                DOM方法
                var elts = document.getElementsByTagName('div');
                for(var i=0;i<elts.length;i++){
                    return true;
                }
                console.log(elts.length);//?
                console.log(elts instanceof Array);//false
                字符串
                console.log('abc'[1]);//b
                console.log('abc'.length);//3
                console.log('abc' instanceof Array);//false
                注意:字符串是不可变值,故把它们当作数组来看时,它们是只读的。push()、sort()、reverse()、splice()等方法会修改数组,它们在字符串上是无效的,且会报错。
               

  • 相关阅读:
    团队冲刺(九)
    TensorFlow利用Keras实现线性回归
    Spark Streaming 编程初级实践
    Spark SQL 编程初级实践
    解决Ubuntu输入正确密码后进不去桌面
    RDD 编程初级实践
    A master URL must be set in your configuration at org.apache.spark.SparkContext.<init>(SparkContext.
    TensorFlow加载mnist数据集并显示
    Spark读取文件统计行数
    【测试技能】服务端测试就是postman看接口和操作redis吗?
  • 原文地址:https://www.cnblogs.com/foodoir/p/5815889.html
Copyright © 2011-2022 走看看