Javascript基础——Javascript语言核心(4):数组

数组

Javascript数组是无类型的:数组元素可为任意类型,同一数组的不同元素也可以有不同类型。

7.1 创建数组

7.1.1 数组直接量

  • 数组直接量中的值不一定是常量,可以为任意表达式
  • 可以包含对象直接量或其他数组直接量
  • 省略数组直接量中的某个值,省略元素为undefined
var empty=[];                //空数组
var misc=[1,true,"a"];       //不同类型元素

var x=1;
var table = [x,x+1,x+2];     //数组定义为了[1,2,3],元素是表达式

var b=[[1,{x:1}],[2,{y:2}]]; //元素是对象或者数组

var count=[1,,3];            
count[1]                     //=> undefined

7.1.2 构造函数Array()

参数 含义 示例
空数组 var a = new Array()等价于[]
1个数值 指定数组长度 var a = new Array(5)
1个非数值 参数成为数组元素 var a = new Array("a")等价于["a"]
多个 同上 var a = new Array(1,true,"a")等价于[1,true,"a"]

7.2 数组元素的读和写

通过[]来访问数组进行读写。

var a=[];
a[0] = 3; //写入元素
a[0]      //=> 3: 读取

数组是对象的特殊形式

  1. 使用[]访问对象属性和对象的属性访问是一样的。特别之处在于,使用小于232非负整数作为属性名,会自动维护其length属性值。
  2. 所有索引都是属性名,只有在0到232-2之间的整数属性名才是索引。
  3. 可以使用非整数或者其他类型作为数组的属性名。
  4. 数组没有“越界”错误的概念,查询不到时,不会报错,只会得到undefined,和对象一样。
var a=["x"];

a[-1] = "y"; //数组a为["x", -1: "y"] 
a[-1]        //"y"
a[1]         //=> undefined : -1并不会占索引位,虽然存在于数组中

a.length     //=> 1: 参考上方第1条,属性名为-1的元素不会计算入length

a["1"] = "z" //数组a为["x", "z", -1: "y"],"1"会转成索引,表示数组的第1个元素(从0开始)

a[true] = 3  //数组a为["x", "z", -1: "y", true: 3],此种情况和"-1"类似

7.3 稀疏数组

稀疏数组是包含从0开始的不连续索引的数组。

通常(上小结中提到的特殊情况除外),数组的length属性代表数组中元素的个数。如果数组是稀疏的,length大于元素个数。

创建稀疏数组的方式:

方式 示例 产生的数组
使用Array()构造函数 var a=new Array(5); (5) [empty × 5]
指定数组的索引值大于当前数组长度 var a=[]; a[4] = 0; (5) [empty × 4, 0]
delete操作符产生 var a=[1,2,3]; delete a[0]; (3) [empty, 2, 3]
省略数组直接量中的值(使用连续逗号) var a=[1,,3] (3) [1, empty, 3]

7.4 数组长度

  • 数组length属性 = 该数组的最大索引 + 1
  • 设置数组length属性,若小于或等于最大索引,数组会被截断
var a=[1,2,3]
a.length     //=> 3: 数组长度为3
a[2]         //=> 3: 最大索引为2

a.length = 2 
a            //=> [1,2]: 数组被截断

a.length = 5
a            //=> [1, 2, empty × 3]: 在数组尾部创建空的区域

ECMAScript 5中,object.defineProperty()(见6.7)可以让数组length属性变成只读,并设置可扩展性(见6.8.3)。

var a=[1,2,3];
Object.defineProperty(a,"length",{writable: false});

a.length=0;
a.length   //=> 3: 不会改变

7.5 数组元素的添加和删除

7.5.1 添加

初始化数组:var a=[1,2]

方式 说明 示例 新数组
新索引赋值 增加新索引并为其赋值 a[2]="x" (3) [1, 2, “x”]
push()方法 在数组末尾增加元素 a.push("x","y") (4) [1, 2, “x”, “y”]
unshift()方法 在数组首部增加元素 a.unshift("x","y") (4) [“x”, “y”, 1, 2]

7.5.2 删除

使用delete运算符。(其他方法详见7.8节)

注意:delete后不会修改数组的length属性,而是变成稀疏数组。 delete和赋值为undefined是有区别的。

var a=[1,2,3];
delete a[0];   //a变为:(3) [empty, 2, 3]
a.length       //=> 3
0 in a         //=> false

a[0]=undefined //a变为:(3) [undefined, 2, 3]
0 in a         //=> true

7.6 数组遍历

使用forEach()方法。

var data=[1,2,3,4,5];
data.forEach(function(x){
    console.log(x) 
})

7.7 多维数组

Javascript不支持真正的多维数组,但可以用数组的数组来近似。

var table = [[1,2,3],["x","y","z"]];

table[0]    //=> [1,2,3]
table[0][0] //=> 1
table[1][2] //=> "z"

7.8 数组的方法

7.8.1 join()

Array.join()将数组中所有元素转化为字符串并连接在一起,返回生成的字符串。

可以指定分隔符默认使用逗号

var a=[1,2,3];
a.join();      //=> "1,2,3"
a.join(' ');   //=> "1 2 3"

var b= new Array(5);
b.join("-");   //=> "----":由于b是长度为5的空数组,所以得到的字符串为4个连接符

7.8.2 reverse()

Array.reverse()将数组中的元素逆序,返回逆序数组。
注意:会改变原数组

var a=[1,2,3];
a.reverse().join() //=> "3,2,1"
a                  //=> [3, 2, 1]

7.8.3 sort()

Array.sort()将数组中的元素排序,返回排序后的数组。
注意:会改变原数组

默认按照字母顺序(区分大小写),undefined会排在尾部

其他方式排序,可以传递一个比较函数,返回负数(参数1在前)、0、正数(参数2在前)。

//--默认排序例子--
var a=["apple","Zoo",,"cat"];
a.sort();                      //=> ["Zoo", "apple", "cat", empty]: 区分大小写
//--传递比较函数,数字排序--
var a=[33,4,1111,222]; 
a.sort()                             //=> [1111, 222, 33, 4]: 默认排序按照字母顺序
a.sort(function(a,b){ return a-b;}); //=> [4, 33, 222, 1111]
a.sort(function(a,b){ return b-a;}); //=> [1111, 222, 33, 4]
//--传递比较函数,不区分大小写的字母排序--
var a=['ant','Bug','cat','Dog'];
a.sort();                        //=>["Bug", "Dog", "ant", "cat"]: 区分大小写
a.sort(function(a,b){
    var al=a.toLowerCase();
    var bl=b.toLowerCase();
    if(al<bl) return -1;
    if(al>bl) return 1;
    return 0;
});                              //=> ["ant", "Bug", "cat", "Dog"]: 不区分大小写

7.8.4 concat()

Array.concat()合并数组,返回新数组,包含原始数组以及各个参数。

var a=[1,2,3];
a.concat(4,5);      //=> [1,2,3,4,5]
a.concat(4,[5,6])   //=> [1,2,3,4,5,6]
a.concat([4,[5,6]]) //=> [1,2,3,4,[5,6]]

7.8.5 slice()

Array.slice()返回指定的数组片段,两个参数分别为开始和结束(不含)位置

位置从0开始计算,如果是负数则从末尾开始,例如-1是最后一个元素。

var a=[1,2,3,4,5];
a.slice(0,2);      //=> [1,2]
a.slice(2,4);      //=> [3,4]
a.slice(1,-1);     //=> [2,3,4]

7.8.6 splice()

Array.splice()在数组中插入或删除元素。
注意:会改变原数组

  • 参数1:插入和(或)删除的起始位置
  • 参数2:删除的元素个数
  • 参数n:需要插入到数组中的元素
var a=[1,2,3,4,5,6,7,8];
a.splice(4); //=> [5,6,7,8], a为[1,2,3,4]
a.splice(1,2)//=> [2,3], a为[1,4],注意上一步已经将a数组改变了,所以得到这样的结果
var a=[1,2,3,4,5];
a.splice(5,0,'x'); //=> [], a为[1,2,3,4,5,"x"]
a.splice(1,3,[4,5],'y')//=> [2,3,4], a为[1,[4,5],"y",5,"x"]

7.8.7 push()pop()

push()和pop()分别在数组尾部添加删除元素。
注意:两个方法都会改变原数组

方法 作用 返回
push() 数组尾部添加元素 数组新长度
pop() 删除最后一个元素 删除的值

组合使用者两个方法,用数组实现先进后出的栈。

var a=[1,2,3];
a.push('x','y'); //=> 5, a为[1,2,3,"x","y"]
a.pop();         //=> "y", a为[1,2,3,"x"]

7.8.8 unshift()shift()

unshift()和shift()分别在数组头部添加删除元素。
注意:两个方法都会改变原数组,且自动调整索引避免空缺。

方法 作用 返回
unshift() 数组头部添加元素 数组新长度
shift() 删除第一个元素 删除的值
var a=[1,2,3];
a.unshift('x','y'); //=> 5, a为["x","y",1,2,3]
a.shift();         //=> "x", a为["y",1,2,3]

7.8.9 toString()toLocaleString()

toString() 等价于join()不带参数的情况。

toLocaleString()是toString()的本地化版本。

[1,[2,3]].toString() //=> "1,2,3"
[4567].toString();              //=> "4567"
[4567].toLocaleString();       //=> "4,567"

var a = new Array(new Date());
a.toString();                   //=> "Mon Jun 11 2018 15:09:57 GMT+0800 (CST)"
a.toLocaleString();             //=> "6/11/2018, 3:09:57 PM"

7.9 ECMAScript 5中的数组方法

注意:ECMAScript 5中的数组方法都不会修改原始数组

7.9.1 forEach()

在7.6有简单介绍了1个参数(遍历的元素)的情况。forEach()还可以使用3个参数:数组元素、元素索引、数组本身

//--1个参数--
var sum=0;
[1,2,3,4,5].forEach(function(x){
    sum+=x;
});
sum //=> 15
//--3个参数--
['x','y','z'].forEach(function(v,i,a){
    console.log(v); //分别是x,y,z
    console.log(i); //分别是0,1,2
    console.log(a); //三次都是["x", "y", "z"]
})

forEach()没有break语句,如果要提前终止,需要把它放在try块中,并能抛出异常。

7.9.2 map()

map()遍历原数组元素,操作后返回一个新数组,原始数组不会修改。

var a=[1,2,3];
a.map(function(x){return x*x;})//=> [1,4,9]
a                              //=> [1,2,3]

7.9.3 filter()

filter()遍历数组返回符合要求的元素组成的数组子集。参数是一个函数,返回true或者fals。

会跳过缺少的元素,返回的数组总是稠密的。

var a=[1,-2,3,4,-5]
a.filter(function(x){return x>0;})                  //=> [1,3,4]
a.filter(function(x,i){return i<2;})                //=> [1,-2]
[1,,2,3].filter(function(){return true;})           //=> [1,2,3]
[1,undefined,null].filter(function(){return true;}) //=> [1, undefined, null]
[1,undefined,null].filter(function(x){return x;})   //=> [1]: undefined 和null在布尔判定都是false

7.9.4 every()some()

every()是否所有元素满足;some()是否存在元素满足。返回结果为布尔型。

var a=[1,2,3,4,5];

a.every(function(x){ return x < 10}) //=> true: 所有值都小于10
a.every(function(x){ return x < 5})  //=> false

a.some(function(x){ return x < 5})   //=> true
[1,'a',2].some(isNaN)                //=> true: "a"不是数字

7.9.5 reduce()reduceRight()

reduce()和reduceRight()使用指定函数,生成单个值。区别在于后者为数组倒序

  • 第1个参数: 函数

  • 第2个参数(可选): 初始值

var a=[1,2,3,4,5]
a.reduce(function(x,y){ return x+y},0)     //=> 15: 求和,初始值为0
a.reduce(function(x,y){return (x>y)?x:y;}) //=> 5: 求最大值

a.reduce(function(x,y){return x.toString()+y.toString()})      //=> "12345"
a.reduceRight(function(x,y){return x.toString()+y.toString()}) //=> "54321"

7.9.6 indexOf()lastIndexOf()

indexOf()和lastIndexOf()搜索数组返回找到满足的第一个元素的索引没有找到返回-1。区别在与后者倒序搜索。

  • 第1个参数: 需要搜索的值

  • 第2个参数(可选): 开始搜索的位置,可以为负数(-1表示最后一个元素)

a=[1,2,3,2];
a.indexOf(2)     //=> 1: a[1]的值为2
a.indexOf(5)     //=> -1: 没有为5的元素
a.indexOf(2,3)   //=> 3: 从索引为3开始搜索
a.lastIndexOf(2) //=> 3: 倒序找到的第一个2是a[3]

7.10 数组类型

ECMAScript 5中,可以使用Array.isArray()判断是否是数组

不能用typeof判断。

typeof([1,2]);        //=> "Object"

Array.isArray([1,2]); //=> true
Array.isArray({});    //=> false

7.11 类数组对象

拥有一个数值length属性和对应非负整数属性的对象成为“类数组对象”。可以用针对真正数组遍历的代码来遍历它们。

可以理解为,它是一个对象,只是碰巧具有以数字为索引的属性。

7.12 作为数组的字符串

ECMAScript 5中,字符串的行为类似于只读数组。除了使用charAt()来访问单个字符外,也可以像数组一样使用[]

var str="abcede";

str.charAt(1);                      //=> "b"
str[1];                             //=> "b"

Array.prototype.join.call(str,"-"); //=> "a-b-c-e-d-e"

猜你喜欢

转载自blog.csdn.net/joyce_lcy/article/details/80626043