JavaScript数组

一、JavaScript中数组的定义

  • 数组的标准定义:一个存储元素的线性集合(collection),元素可以通过索引来引用任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量。
  • JavaScript数组的定义:是一种特殊的对象,用来表示偏移量的索引是该对象的属性,索引可能是整数。然而,这些数字索引在内部是被转换成字符串类型的,这是因为JavaScript对象中的属性必须是字符串类型,内部的元素可以使任意类型的。

二、数组的操作

1. 创建数组

  • 方式一:
var numbers = [];
  • 方式二:
// 当传入一个数字类型的参数时,表示数组的长度,其他则表示数组的元素。
var numbers = new Array();

这两种方式推荐使用方式一,因为这种方式效率更高。

2. 读写数组

一般使用 [] 操作符

3. 由字符串生成数组

split() 方法:

  • 作用:通过分隔符,将字符串分成几部分,并将每部分作为一个元素保存在一个新的数组中。
  • 参数:分隔符
  • 返回值:新的数组
  • 元字符串不发生改变。
var str = 'hello world javascript css html';
var words = str.split(' '); // words为一个数组

4. 对数组的整体操作

4.1 将一个数组赋值给另一个数组

改操作只是给被赋值的数组增加了一个新的引用,其实两个变量指向的是一个数组,两者的操作是相互影响的。通常被称为“浅复制”。
如何实现深复制:

// 将arr1深复制给arr2
function copy (arr1,arr2) {
  for (var i = 0; i < arr1.length; i++) {
    arr2[i] = arr1[i]
  }
}

拓展:如何实现一个对象的深复制?

function copyObj (obj1, obj2) {
  var obj2 = obj2 || {};
  for (item in obj1) {
    if (typeof item === 'object') {
      obj2[item] = (obj1[item].constructor === Array):[]?{}; // 判断属性是否为对象或是数组
      copyObj(obj1[item], obj2[item]);
    }else{
      obj2[item] = obj1[item]
    }
  }
  return obj2;
}

5. 存取操作

5.1 查找匹配元素
5.1.1 indexOf():
  • 作用:用来查找传进来的参数在目标函数中是否存在;
  • 参数:要查找的内容
  • 返回值:如果有,则返回改元素在目标数组中的索引,如果不存在则返回-1
  • 原数组不发生改变
var names = ['huangjin','qq','jack','hellen'];
var postion = names.indexOf('qq')
console.log(postion); // 1
5.1.2 slice():
  • 作用:数组的查询
  • 参数:slice(n,m):从索引n开始,查询到索引为m前,不包含m
  • 返回值:把找到的以新的数组返回
  • 原来数组不发生改变
  • 特殊情况:
    • 如果只写一个参数是,则从指定索引找到末尾
    • slice(0)和slice(),表示数组克隆
    • 支持负数索引,如果传递了负数,浏览器解析时是按总长度+负数索引 来处理的
5.2 数组的字符串表示
5.2.1 toString():
  • 作用:将数组转换成字符串,各元素用逗号隔开
  • 参数:无
  • 返回值:各元素以逗号分隔的字符串
  • 原数组不发生改变
var names = ['huangjin','qq','jack','hellen'];
console.log(names.toString()); 
5.2.2 join():
  • 作用:将数组转换成字符串,各元素用指定的分隔符分隔
  • 参数:分隔符
  • 返回值:各元素以指定分隔符链接的字符串
  • 原数组不发生改变
console.log(names.join('-')); // huangjin-qq-jack-hellen
5.3. 由已有数组创建新的数组
5.3.1 concat():
  • 作用:合并多个数组,方法的调用者为一个数组,作为参数的数组会被链接到调用数组的而后面;
  • 参数:一个或者多个,可以使数组,或其他类型
  • 返回值:合并后的新数组
  • 原数组不发生改变。
console.log(names.concat(['aaa','bbb']));
VM629:1 (6) ["huangjin", "qq", "jack", "hellen", "aaa", "bbb"]

console.log(names.concat(['aaa','bbb'],'ccc'));
VM631:1 (7) ["huangjin", "qq", "jack", "hellen", "aaa", "bbb", "ccc"]

console.log(names.concat(['aaa','bbb'],'ccc',123));
VM633:1 (8) ["huangjin", "qq", "jack", "hellen", "aaa", "bbb", "ccc", 123]

5.3.2 splice(n,m):
  • 作用:截取一个数组的子集作为一个新的数组
  • 参数:第一个是截取的开始索引,第二个为结束索引,如果第二个不传,则一直截取到末尾,如果两个参数都不传,则不截取;
  • 返回值:截取出来的元素组成的新数组
  • 原数组改变
names = ['a','b','c','d','e'];

console.log(names.splice(1,2));
VM837:1 (2) ["b", "c"]

console.log(names);
VM839:1 (3) ["a", "d", "e"]

console.log(names.splice(1));
VM841:1 (2) ["d", "e"]

console.log(names);
VM843:1 ["a"]

console.log(names.splice());
VM845:1 []

console.log(names);
VM847:1 ["a"]

拓展:splice可以用于增加和删除数组元素,删除操作跟上面一样,只是这是删除是相对于原数组,而上面的是相对于返回值。所以删除就不做介绍,这里主要讲解一下新增元素。如下:

  • splice(n,m,x):在原有删除的基础上,用x替换删除的内容
    • 返回值:被替换的原有值
    • 原数组发生改变
  • 增加操作:
    • splice(n,0,x):在修改的基础上,一项都不删除,把x插入到索引n的前面
names = ['a','b','c']

console.log(names.splice(1,0,'d'));
VM928:1 []

console.log(names);
VM953:1 (4) ["a", "d", "b", "c"]

6. 可变函数

JavaScript的数组的可变函数主要是用来在不引用数组中某个元素的情况下,改变数组内容。

6.1 从数组的首尾添加元素
6.1.1 push():
  • 作用:将一个元素添加到数组末尾
  • 参数:要添加的元素内容,可以是多个
  • 返回值:添加新元素后数组的长度
  • 原数组改变
var names = ['a','b','c']

names.push('d')
4
console.log(names)
VM297:1 (4) ["a", "b", "c", "d"]
6.1.2 unshift():
  • 作用:将一个元素添加到数组的前面
  • 参数:要添加的元素内容,可以是多个
  • 返回值:添加新元素后的数组长度
  • 原数组改变
console.log(names)
VM297:1 (4) ["a", "b", "c", "d"]

console.log(names.unshift(1));
VM351:1 5

console.log(names)
VM353:1 (5) [1, "a", "b", "c", "d"]
6.2 从数组的首尾删除元素
6.2.1 pop():
  • 作用:删除数组末尾的元素
  • 参数:无
  • 返回值:删除末尾元素后数组的长度
  • 原数组改变
6.2.2 shift():
  • 作用:删除数组的第一个元素,数组后面的袁术向前移动一位
  • 参数:无
  • 返回值:删除元素后数组的长度
  • 原数组改变
6.3 从数组的中间位置添加和删除元素

splice():

  • splice(n,m):从第n到m删除
    • 返回值:被删除的元素
    • 原数组发生改变
  • 增加操作:
    • splice(n,0,x):在修改的基础上,一项都不删除,把x插入到索引n的前面
6.4 数组排序
6.4.1 reverse():
  • 作用:颠倒数组
  • 参数: 无
  • 返回值:颠倒后的数组
  • 原数组改变
6.4.2 sort():
  • 作用:按规则排列数组
  • 参数:无或者回调函数,当无参数时,按照Unicode排序
  • 返回值:排序后的数组
  • 原数组改变
function compare(a,b) {
  return a-b; // 如果为正,按升序,为0位置不变,为负则按降序
}
var nums = [1,2,5,3,55,43,4];
nums.sort(compare);

7. 迭代器方法

7.1 不生成新数组的迭代器方法

即,不产生任何新的数组,要么对于数组中的每个元素执行某种操作,要么返回一个值。

7.1.1 forEach():
  • 作用:对数组中的每个元素进行规定的操作
  • 参数:函数,即对每个元素执行的操作函数
  • 返回值:无
  • 原数组不改变
console.log(names)
VM586:1 (5) [1, "a", "b", "c", "d"]

console.log(names.forEach(function(a){console.log('f'+a)}));
VM624:1 f1
VM624:1 fa
VM624:1 fb
VM624:1 fc
VM624:1 fd
VM624:1 undefined

console.log(names)
VM626:1 (5) [1, "a", "b", "c", "d"]
7.1.2 every():
  • 作用:匹配所有元素都复合某个规则
  • 参数:返回值为布尔类型的函数
  • 返回值:如果数组中的每个元素经过该函数返回为true,则返回为true,否则为false
  • 原数组不发生改变
var nums = [1,2,3,4,5]

nums.every(function(i){if(i>0){return true}});
true
nums.every(function(i){if(i>1){return true}});
false
7.1.3 some():
  • 作用:匹配数组中是否有元素都复合某个规则
  • 参数:返回值为布尔类型的函数
  • 返回值:如果数组中的只要有一个元素经过该函数返回为true,则返回为true,否则为false
  • 原数组不发生改变
7.1.4 reduce():
  • 作用:接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
  • 参数:用于执行每个数组元素的函数
  • 返回值:返回计算结果
  • 原数组不改变
var numbers = [65, 44, 12, 4];
 
function getSum(total, num) {
    return total + num;
}
function myFunction(item) {
    console.log(numbers.reduce(getSum));
}
7.2 生成新数组的迭代器方法
7.2.1 map():
  • 作用:类似于forEach(),区别在于map()会返回一个新数组
  • 参数:用于执行每个数组元素的函数
  • 返回值:返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
  • 原数组不改变
var numbers = [4, 9, 16, 25];

function myFunction() {
    console.log(numbers.map(Math.sqrt));
}
7.2.2 filter():
  • 作用:和every() 类似,区别在于every()返回的是布尔值,而filter() 返回的是新数组,该数组包含应用回调函数后值为true的元素
  • 参数:用于执行每个数组元素的函数
  • 返回值:返回一个包含应用回调函数后值为true的元素的数组
  • 原数组不改变

三、总结

  • JavaScript中的数组其实是一个特殊的对象
  • 创建数组的方式主要有两种,但常用的是 [] 的形式
  • 数组转字符串:toString()、 join()
  • 字符串转数组:split()
  • 数组的增删改查:
    • 增加:push()、 unshift()、 splice(n,0,x)、 concat()
    • 删除:pop()、shift()、splice(n,m)
    • 更改:splice(n,m,x)
    • 查询:indexOf()、slice(n,m)
  • 数组排序: reverse()、sort()
  • 数组遍历: forEach()、map()、every()、some()、filter()等
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • 这里先提一下for in 循环,因为之前在C++ 和 OC中用到过快速遍历,但是发现JavaScript有所不同,...
    Allen_HD阅读 299评论 0 1
  • 数组的基本特点 数组元素是任意类型的 可能的最大索引是2^32-2,默认起始索引是 0 Javascript的数组...
    dooze阅读 478评论 0 1
  • 创建数组的基本方式: var colors = new Array(); 在用构造函数创建时候可以同时给它传递数量...
    编程_浪子阅读 300评论 0 1
  • 秋凉,悲戚着,诉说着 下一个冬季的来临,或许你不会出现 等待可以延长 像相遇时的偶然 我,不曾别离 只是怅然 风,...
    菜花的小青春阅读 202评论 0 0
  • 春水初生,春林初盛,春风十里,不如你。 ——冯唐 冯唐的这首诗自创作出来,便像病毒一样迅速传播,因为它实在太浪漫。...
    少少帮主阅读 4,838评论 0 4