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()等方法会修改数组,它们在字符串上是无效的,且会报错。

javascript中的数组扩展(一)的更多相关文章

  1. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  2. Javascript中判断数组的正确姿势

    在 Javascript 中,如何判断一个变量是否是数组? 最好的方式是用 ES5 提供的 Array.isArray() 方法(毕竟原生的才是最屌的): var a = [0, 1, 2]; con ...

  3. JavaScript中的数组详解

    JavaScript中的数组 一.数组的定义 数组是值的有序集合,或者说数组都是数据的有序列表. 二.创建数组 [字面量形式] 1.空数组 var arr=[]; 2.带有元素的数组 var arr= ...

  4. JavaScript中对数组的操作

    原文:JavaScript中对数组的操作 一:数组的使用 1.定义:JavaScript中对数组的定义有两种形式.如: .var arr = [12,3,5,8]; .var arr = new Ar ...

  5. JavaScript中对数组和数组API的认识

    JavaScript中对数组和数组API的认识 一.数组概念: 数组是JavaScript中的一类特殊的对象,用一对中括号“[]”表示,用来在单个的变量中存储多个值.在数组中,每个值都有一个对应的不重 ...

  6. JavaScript中的数组和字符串

    知识内容: 1.JavaScript中的数组 2.JavaScript中的字符串 一.JavaScript中的数组 1.JavaScript中的数组是什么 数组指的是数据的有序列表,每种语言基本上都有 ...

  7. JavaScript中的数组创建

    JavaScript中的数组创建 数组是一个包含了对象或原始类型的有序集合.很难想象一个不使用数组的程序会是什么样. 以下是几种操作数组的方式: 初始化数组并设置初始值 通过索引访问数组元素 添加新元 ...

  8. JavaScript中Array(数组) 对象

    JavaScript中Array 对象 JavaScript中创建数组有两种方式 (一)使用直接量表示法: var arr4 = []; //创建一个空数组var arr5 = [20]; // 创建 ...

  9. JavaScript中一个对象数组按照另一个数组排序

    JavaScript中一个对象数组按照另一个数组排序 需求:排序 const arr1 = [33, 11, 55, 22, 66]; const arr2 = [{age: 55}, {age: 2 ...

随机推荐

  1. C# 修改webbrowser 的 useragent

    Also, there is a refresh option in the function (according to MSDN). It worked well for me (you shou ...

  2. Ios开发之定位CLLocationManager

    Ios中的定位功能是通过 Core Location框架实现的.它和地图开发框架是相互独立的.在Core Location中主要实现了定位和地理编码的功能! 下面我们就来介绍一下它的属性,方法和代理方 ...

  3. asp.net 的page 基类页面 做一些判断 可以定义一个基类页面 继承Page类 然后重写OnPreLoad事件

    public class BasePage:Page protected override void OnPreLoad(EventArgs e){     base.OnPreLoad(e);    ...

  4. 网页内容导出word/excel的js代码

    IE设置: 工具-> Internet选项-> 安全->自定义级别-> 对没有标记安全级别的ActiveX控件进行初始化  设为启用! 1.导出word //指定区域导出到Wo ...

  5. 是时候放弃sublime了

    今天下午在忍无可忍之下终于卸载了sublime,最为一个在gui下最顺手的编辑器,放弃是需要非常充足的理由的. 放弃sublime无非是因为以下几点原因: 收费.我用的是未注册版的sublime,保存 ...

  6. whoami 和 Who am i

    ① 两个命令在一般的情况下,似乎效果是一样的 ② 但是当你执行完su 命令切换用户后,就不一样了,who am i 显示最早login的账户,而whoami 显示切换后的账户 例如: -bash-3. ...

  7. 如何闪开安装VS2013必须要有安装IE10的限制

    把下面这一段文字,储存成.bat档案,然后右击以管理员角色去执行它.@ECHO OFF :IE10HACK REG ADD "HKLM\SOFTWARE\Wow6432Node\Micros ...

  8. ffmpeg安装的问题

    php语音转换需要安装ffmpeg文件 参考地址: http://thierry-xing.iteye.com/blog/2017864 http://diogomelo.net/blog/11/en ...

  9. 一种线程安全的handle

    对象引用的正确性在多线程环境下是一个复杂的问题,请参考,处理由引用计数引起的泄漏.简单来说,我们应该尽量减少使用强引用,否则将有可能产生[处理由引用计数引起的泄漏]一文中描述的难以察觉的内存泄漏问题. ...

  10. 一次流量稍高导致web项目慢的问题&解决

    项目上线后,用户越来越多,有一天出现一个issue:用户访问特别慢. 首先介绍下架构: haproxy/Nginx / \ node1 node2 | | redis redis(slave) | | ...