Javascript数组详解

数组的定义

数组是按序号排列的一组值,每个值的位置都有编号(从0开始)。数组本质上是一种特殊的对象。它的键名是按(0,1,2...)排列的一组数字。

  1. 创建数组:

    var arr = new Array(values);
    var arr = [vaules];
    
  2. 判断比是否是个数组

    • Array.isArray(arr)
    • arr instanceof Array
  3. 取数组元素
    arr[index]

  4. length 属性
    返回数组的成员数量。
    Javascript使用一个32位整数,保存数组的元素个数。这意味着数组的成员最多只有4294967295个(232-1)。

    var arr = ['a','b'];
    arr.length  // 2
    arr.[10] = 'c'
    arr.length //11
    

    从上面的输出结果可以看出,length属性可以动态变化,如果将length属性设为 0 ,就会将数组清空。如果设置的数小于原有的个数,那么在这个数后面的数值就自动删除了。反过来,如果设置的数大于原有的个数,数组的成员将增大,都为 undefined

    var a = [1,2];
    a.length = 5;
    a[4] // undefined
    a.length = 1;
    a.[1] // undefined
    a.length = 0;
    a  //[]
    
  5. 增加数组元素

    • push()方法 在数组的末尾增加一个或多个元素,并返回数组的新长度。
    • unshift()方法 在数组的开头增加一个或多个元素,并返回数组的新长度。
    • length 属性
    var arr = [1, 2, 3]
    arr.push(4)
    arr  // 1, 2, 3, 4
    arr.unshift(6)
    arr  // 6, 1, 2, 3, 4
    arr[arr.length] = 7  // 与push()方法类似
    arr  // 6, 1, 2, 3, 4, 7
    
    
  6. 删除数组中的元素

    • delete 运算符,可以删除数组中的某个元素,但这不会改变length属性的值.
    • pop() 方法 删除数组的最后一个元素,并返回这个元素。
    • shift() 方法 删除数组的第一个元素,并返回这个元素。
    var arr = [1,2,3];
    delete arr[0];
    arr   // [undefined,2,3]
    arr.length  // 3
    var last = arr.pop()
    var first = arr.shift()
    last // 3
    first // undefined
    arr //2
    

类数组对象

在js中,有些对象被叫做“类数组对象”(array-like object),因为这些对象看起来很像数组,可以使用length属性,但是无法使用数组的方法。
典型的类数组对象是函数的arguments对象,以及大多数DOM元素集,还有字符串。

// arguments对象
function args() {return arguments; }
var arraylike = args('a','b')
arrayLike[0]  // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false
Array.isArray(arrayLike)  // false

// DOM元素集
var elts = document.getElementsByTagName('p');
elts.length  // 3
eles instanceof Array  // false

//字符串
'abc'[1]  // 'b'
'abc'.length  // 3
'abc' instanceof Array  // false

数组的slice方法能将类数组对象,变成真正的数组。slice方法后面会结介绍。

var arr = Array.prototype.slice.call(arrayLike);

数组的遍历

  1. for...in 循环

    var a =[1, 2, 3];
    a.other = 'other';
    for (var i in arr){
        console.log( arr[i]);
    }
    // 1, 2, 3, other
    

    从上面的输出结果可以看出,利用for..in循环会将动态添加的非数字键的值遍历出来,因此需要使用的时候需要注意。

  2. for 循环和 while 循环

    var a = [1, 2, 3];
    
    // for循环
    for(var i = 0; i < a.length; i++) {
      console.log(a[i]);
    }
    
    // while循环
    var i = 0;
    while (i < a.length) {
      console.log(a[i]);
      i++;
    }
    
    var l = a.length;
    while (l--) {
      console.log(a[l]);
    }
    
  3. forEach()方法

    //array.forEach(callback[, thisArg])
    //callback 在数组的每一项上执行的函数,接受三个参数:item: 数组当前项的值,index: 当前项的索引,arr:数组本身。
    var arr = [1, 2, 3]
    arr.forEach(function(item, index, arr){
        console.log(item, index);
    });
    //1 0
    //2 1
    //3 2
    

数组常用的方法

数组常用的方法
  1. join() 将数值转换为字符串

    var arr = [1, 2, 3];
    arr.join(); // "1,2,3"
    arr.join("_"); // "1_2_3"
    
  2. reverse() 将数组逆序

    // 原数组会被修改
    var arr = [1, 2, 3];
    arr.reverse(); // [3, 2, 1]
    arr; // [3, 2, 1]
    
  3. sort() 数组排序
    默认情况下是升序排列的,底层是调用了每个数组项的 toString() 方法,然后比较得到字符串,即使每个数组项的数值是数字,比较的也是字符串。

    // 原数组会被修改
    var arr = [1, 12, 213, 1432, 'a'];
    arr.sort(); // [1, 12, 1432, 213, "a"]
    arr.sort(function(a, b){
        return b-a; //按倒序排列数组
    });
    
    
  4. concat() 数组合并
    用法:array.concat(value1, value2, ..., valueN)

    // 原数组不会被修改
    var arr =[1, 2, 3]
    arr.concat(4, 5);
    arr; //[1, 2, 3]
    arr.concat([11,2],3); // [1, 2, 3, 11, 2, 3]
    
  5. slice() 返回部分数组
    用法:array.slice(begin[,end])

    slice用于复制数组,复制完后旧数组不变,返回得到的新数组是旧数组的子集。

    第一个参数begin是开始复制的位置,需要注意的是,可以设负数。设负数表示从尾往前数几个位置开始复制。例如slice(-2)将从倒数第2个元素开始复制。另外需要注意的是,该参数虽未标注为可选,但实际上是可以省略的,省略的话默认为0。

    第二个参数end可选,表示复制到该位置的前一个元素。例如slice(0,3)将得到前3个元素,但不包含第4个元素。不设的话默认复制到数组尾,即等于array.length。

    //原数组不会被修改
    var arr = [1, 2, 3, 4, 5];
    arr.slice(); //[1, 2, 3, 4, 5]
    arr.slice(1,3); // [2, 3]
    arr.slice(1, -1); // [2, 3, 4]
    arr; // [1, 2, 3, 4, 5]
    
  6. splice() 数组拼接
    用法:array.splice(start, deleteCount[, item1[, item2[, ...]]])

    • start 指要从哪一位开始修改内容,如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位。
    • deleteCount 表示要移除的数组元素的个数
    • item 要添加进数组的元素

    最主要的的用途是向数组的中部插入元素。

    //原数组会被修改
    var arr = [1, 2, 3, 4, 5];
    //从第三个数组元素删除
    arr.splice(2); // returns [3, 4, 5] 
    arr; // [1, 2]
    //从第三个数组元素删除,删除两个元素
    arr.splice(2, 2) // returns [3, 4]
    arr; // [1, 2, 5]
    //将'a','b'替换到数组的第二个元素
    arr.splice(1, 1, 'a', 'b')
    
    
  7. forEach() 数组遍历
    用法:array.forEach(callback[, thisArg])
    callback 在数组的每一项上执行的函数,接受三个参数:item:数组当前项的值,index: 当前项的索引,arr:数组本身。

    var arr = [1, 2, 3]
    arr.forEach(function(item, index, arr){
        console.log(item, index);
    });
    //1 0
    //2 1
    //3 2
    
  8. map() 数组映射
    map映射创建新数组,用法: map(function(value, index, array) { … }, [thisArg] );。和forEach一样,不赘述。唯一需要注意的的是回调函数需要有return值,否则新数组都是undefined。

    其实map能干的事forEach都能干,你可以把map理解为forEach的一个特例,专门用于:通过现有的数组建立新数组。

    //原数组未被修改
    var arr= [1, 2, 3];
    arr.map(function(x){
        return x+10;  // 需要 return 值,否则新数组里都是 undefined
    });  // [11, 12, 13]
    arr; // [1, 2, 3]
    
  9. filter() 数组过滤
    filter用于过滤数组,用法: filter( function(value, index, array) { … }, [thisArg] ); 。唯一需要注意的的是回调函数需要return布尔值true或false,

    //原数组未被修改
    var arr= [1, 2, 3, 4, 5, 6, 7, 8];
    arr.filter(function(x,index){
        return x%2 == 0;
    }); // [2, 4, 6, 8]
    arr; // [1, 2, 3, 4, 5, 6, 7, 8]
    
  10. every() some() 数组判断
    some表示只要某一个满足条件就OK,every表示全部满足条件才OK。
    用法:

    • arr.every(callback[, thisArg])
    • arr.some(callback[,thisArg])
    var arr= [1, 2, 3, 4, 5];
    arr.every(function(x){
        return x < 6;
    }); // true
    arr.every(function(x){
        return x > 6;
    }); // false
    arr.some(function(x){
        return x === 1;
    });  // true
    arr.some(function(x){
        return x === 6;
    }); // false
    
  11. reduce() reduceRight()
    reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。 两者都是用于迭代运算。区别是reduce从头开始迭代,reduceRight从尾开始迭代。

    用法: reduce( function(previousValue, currentValue, currentIndex, array) { … }, [initialValue] );

    第一个参数是回调函数,有4个参数:previousValue,currentValue,currentIndex,array。看名字也能知道意思:前一个值,当前值,当前索引,数组本身。

    第二个参数initialValue可选,表示初始值。如果省略,初始值为数组的第一个元素,这样的话回调函数里previousValue就是第一个元素,currentValue是第二个元素。因此不设initialValue的话,会少一次迭代。

    //将数组所有项相加
    var arr = [0, 1, 2, 3];
    var sum = arr.reduce(function(a, b) {
     return a + b
    }, 0); // 6
    arr; //[0, 1, 2, 3]
    //数组扁平化
    var flattened = [[0, 1], [2, 3], [4, 5]];
    flattened.reduce(function(a,b){
        return a.concat(b);
    }); // returns [0, 1, 2, 3, 4, 5]
    
  12. indexOf() lastIndexOf() 数组检索
    用法:indexOf( searchElement, [fromIndex = 0]) / lastIndexOf( searchElement , [fromIndex = arr.length – 1])
    第一个参数searchElement即需要查找的元素。第二个参数fromIndex可选,指定开始查找的位置。如果忽略,indexOf默认是0,lastIndexOf默认是数组尾。
    两者都用于返回项目的索引值。区别是indexOf从头开始找,lastIndexOf从尾开始找。如果查找失败,无匹配,返回-1

    var arr = ['a', 'b', 'c', 'd', 'e'];
    arr.indexOf('c');  // 2 找到返回数组下标
    arr.indexOf('c', 3); // -1 指定从3号位开始查找
    arr.indexOf('f'); // -1 没找到该元素
    arr.lastIndexOf('c'); // 2
    arr.lastIndexOf('c',2); // 2
    arr.lastIndexOf('f'); // -1 没找到该元素
    
  13. isArray() 判断是否是数组
    用法:Array.isArray(value)

    var arr = [];
    var a = "not array";
    Array.isArray(arr); // true
    Array.isArray(a); // false
    

参考资料

MDN

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容