javascript之数组array详情

创建数组

使用字面量语法和Array()构造函数。

字面量

使用数组字面量是创建数组最简单的方法,在方括号内将数组元素用都好隔开即可。

var s = [];//空数组
var s = [1,1,1,1,1]//有5个值的数组。

虽然javascript数组与其他语言中数组都是数据的有序列表,但是与其他语言不同的是,js的每一项可以保留任何类型的数据。

var s = [1,true,'a'];

数组字面量不一定是常量,它可以是任意表达式。

var base = 1024;
var table = [base,base+1,base+2,base+3];

可以包含对象字面量或者其他数组字面量。

var s = [[1,{a:2,y:3}],[2,{w:8,r:7}]];

如果数组的元素还是数组,就是多维数组。

var s = [[1, 2], [3, 4]];

使用数字字面量表示法时,不会调用Array构造函数。

函数构造

有三种方式调用构造函数

1:没有参数,创建一个空数组。

//该方法用于创建一个空数组,相当于[];
var s = new Array();

2: 有一个参数,该参数用于指定数组的长度。

var s = new Array(10);
console.log(s);//[];
console.log(a[0],a.length);//undefined 10

3: 如存在 一个其他的类型的参数,则会创建一个含那个值的只有一项的数组。

var s = new Array('10');
console.log(s);//['10']
console.log(s.length);//1

4: 有多个参数的时候参数代表具体的数组元素,

var a = new Array(1,2,3);
console.log(a);//[1,2,3]
console.log(a[0],a[1],a[2]);//1 2 3

5:使用Array构造函数时,可以省略new操作符号。

var a1 = Array();
var a2 = Array(10);
var a3 = Array(1,2,3);
console.log(a1,a2,a3);//[] [] [1,2,3]

数组本质

数组是按次序排列的一组值,本质上数组是一种特殊的对象。

typeof [1,2,4];// object;

数组的特殊性体现在,它的键名是按次序排列的一组整数(0,1,2,3);由于数组成员的键名是固定的,应次数组不用为每个元素指定键名。而对象的每个成员都必须指定键名。

var s = [1,2,3,5];
console.log(Object.key(s));// ["0", "1", "2"];

var obj = {
    name1: 'a',
    name2: 'b',
    name3: 'c'
};

数组是对象的特殊形式,使用方括号访问数组元素,就像方括号访问对象的属性一样。

js语言规定,对象的键名一律为字符串,所以,数组的键名其实也是字符串,之所有可以用数组来读取,是因为非字符串的键名会被转为字符串,然后,将其作为属性名来使用。

o={};       //创建一个普通的对象
o[1]="one"; //用一个整数来索引它

//数值键名被自动转成字符串
var arr = ['a', 'b', 'c'];
arr['0'] // 'a'
arr[0] // 'a'

  但是,一定要区分数组索引和对象的属性名:所有的索引都是属性名,但只有在0~2(32次方)-2(4294967294)之间的整数属性名才是索引
  

var a = [];

//索引
a['1000'] = 'abc';
a[1000] // 'abc'

//索引
a[1.00] = 6;
a[1] // 6

单独的索引不能做表示符,所以数组元素只能用方括号法表示。

var arr = [1, 2, 3];
arr[0];//1
arr.0;//SyntaxError

可以使用负数和非整数来索引数组,由于其不在0~2的32次方-2的范围内,所以,只是数组的属性名。而不是数组的索引,明显的特征是不会改变数组的长度。

//属性名
a[-1.23]=true;
console.log(a.length);//3

//索引
a[10] = 5;
console.log(a.length);//11

//属性名
a['abc']='testing';
console.log(a.length);//11

*稀疏数组*

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

知道稀疏数组的、最直接的方式就是使用delete操作符。

var a = [1,2,3,4,5];
delete a[1];//删除索引为一的元素。
console.log(a[1]);//undefined
console.log(1 in a);//false

数组的逗号之间可以省略元素值,通过省略元素值也可以知道稀疏数组。

var a =[1,,3,4,5];
console.log(a[1]);//undefined
console.log(1 in a);//false

如果数组的末尾使用逗号,浏览器之间有差别。标准浏览器会忽略该逗号,而IE8会在末尾田间undefined.

//标准浏览器输出[1,2],而IE8-浏览器输出[1,2,undefined]
var a = [1,2,];
console.log(a);

//标准浏览器输出2,而IE8-浏览器输出3
var a = [,,];
console.log(a.length);

足够稀疏的数组通常在实现上比稠密的数组更慢,内存利用率更高,在这样的数组中查找元素的时间与常规对象属性的查找时间一样长.

数组长度

每个数组有一个length属性,就是这个属性使其区别于常规的javascript对象。针对稠密(也就是非稀疏)数组,length属性值代表数组中元素的个数,其值比数组中最大的索引大1。

[].length     //=>0:数组没有元素
['a','b','c'].length   //=>3:最大的索引为2,length为3

 当数组是稀疏数组时,length属性值大于元素的个数,同样地,其值比数组中最大的索引大1
 

[,,,].length; //3
(Array(10)).length;//10
var a = [1,2,3];
console.log(a.length);//3
delete a[1];
console.log(a.length);//3

数组的特殊性主要体现在数组长度是可以动态调整的:

  1. 如果为一个数组元素赋值,索引i大于等于现有数组的长度时,length属性的值将设置为i+1
var arr = ['a', 'b'];
arr.length // 2

arr[2] = 'c';
arr.length // 3

arr[9] = 'd';
arr.length // 10

arr[1000] = 'e';
arr.length // 1001
  1. 设置length属性为小于当前长度的非负整数n时,当前数组索引值大于等于n的元素将从中删除
a=[1,2,3,4,5];   //从5个元素的数组开始
a.length = 3;    //现在a为[1,2,3]
a.length = 0;    //删除所有的元素。a为[]
a.length = 5;    //长度为5,但是没有元素,就像new Array(5)

将数组清空的一个有效方法,就是将length属性设为0;

  1. 将数组的length属性值设置为大于其当前的长度。实际上这不会向数组中添加新的元素,它只是在数组尾部创建一个空的区域.
var a = ['a'];
a.length = 3;
console.log(a[1]);//undefined
console.log(1 in a);//false

如果人为设置length为不合法的值(即0——232-2范围以外的值),javascript会报错

// 设置负值
[].length = -1// RangeError: Invalid array length

// 数组元素个数大于等于2的32次方
[].length = Math.pow(2,32)// RangeError: Invalid array length

// 设置字符串
[].length = 'abc'// RangeError: Invalid array length

 由于数组本质上是对象,所以可以为数组添加属性,但是这不影响length属性的值
 

var a = [];

a['p'] = 'abc';
console.log(a.length);// 0

a[2.1] = 'abc';
console.log(a.length);// 0

数组遍历

使用for循环遍历数组元素是最常见的方法

var a = [1, 2, 3];
for(var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

也可以使用while循环

var a = [1, 2, 3];
var l = a.length;
while(l--) {
    console.log(a[i]);
}

如果数组是稀疏数组,使用for循环需要添加一些额外的条件

//跳过不存在元素
var s = [1,,,6];
for(var i=0;i<s.length;i++){
    if(!(i in a)){
        continue
    }else{
        console.log(a[i])
    }
}

使用for/in循环处理稀疏数组。循环每次,将一个可枚举的属性名(包括数组索引)付给循环变量。不存在的索引将不会被遍历到

var s = [1,,,2];
for(var i in s){
    console.log(s[i]);
}

由于for/in循环能够枚举继承的属性名,如添加到Array.prototype中的方法。由于这个原因,在数组上不应该使用for/in循环,除非使用额外的检测方法来过滤不想要的属性.

var a = [1,,,2];
a.b = 'b';
for(var i in a){
    console.log(a[i]);//1 2 'b'
}
//跳过不是非负整数的i
var a = [1,,,2];
a.b = 'b';
for(var i in a){
    if(String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    console.log(a[i]);//1 2
}

javascript规范允许for/in循环以不同的顺序遍历对象的属性。通常数组元素的遍历实现是升序的,但不能保证一定是这样的。特别地,如果数组同时拥有对象属性和数组元素,返回的属性名很可能是按照创建的顺序而非数值的大小顺序。如果算法依赖于遍历的顺序,那么最好不要使用for/in而用常规的for循环.

类数组

拥有length属性和对应非负整数属性的对象叫做类数组(array-like object);

var s = {};
var i = 0;
while (i < 10){
    s[i] = i*i;
    i++;
}
s.length = i;


var total = 0;
for(var j = 0; j < a.length; j++){
    total += a[j];
}

有三个常见的类数组对象:

1: arguments对象

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

DOM方法(如document.getElementsByTagName()方法)返回的对象

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

字符串

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

字符串是不可变值,故当把它们作为数组看待时,它们是只读的。如push()、sort()、reverse()、splice()等数组方法会修改数组,它们在字符串上是无效的,且会报错

var str = 'abc';
Array.prototype.forEach.call(str, function(chr) {
  console.log(chr);//a b c
});

Array.prototype.splice.call(str,1);
console.log(str);//TypeError: Cannot delete property '2' of [object String]

数组的slice方法将类数组对象变成真正的数组

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

 javascript数组方法是特意定义为通用的,因此它们不仅应用在真正的数组而且在类数组对象上都能正确工作。在ECMAScript5中,所有的数组方法都是通用的。在ECMAScript3中,除了toString()和toLocaleString()以外的所有方法也是通用的
 

var a = {'0':'a','1':'b','2':'c',length:3};
Array.prototype.join.call(a,'+');//'a+b+c'
Array.prototype.slice.call(a,0);//['a','b','c']
Array.prototype.map.call(a,function(x){return x.toUpperCase();});//['A','B','C']

感觉都升华了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值