• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
cc7777
博客园    首页    新随笔    联系   管理    订阅  订阅

数组Array

1.定义

数组(array)是按次序排列的一组值。每个值的位置都有编号(从0开始),整个数组用方括号表示。

任何类型的数据,都可以放入数组。

var arr = [
  {a: 1},
  [1,2,3],
  function(){return true;}
];

arr[0]//Object {a:1}
arr[1]//[1,2,3]
arr[2]//function(){return true;}

2、数组的本质

本质上,数组属于一种特殊的对象。typeof  返回数组的类型是 object 。

数组的特殊性提现在,它的键名是按次序排列的一组整数 ( 0, 1, 2... ) 。

var arr = ['a', 'b', 'c'];

Object.keys(arr)//["0", "1", "2"]

JavaScript语言规定,对象的键名一律为字符串,所以,数组的键名也是字符串。之所以可以用数值读取,是因为非字符串的键名会被转为字符串。

var a = [];

a[1.00] = 6;

a[1] //6

上面的代码中,由于 1.00 转换成字符串是 1,所以通过数字键 1 可以读取值。

3、length 属性

只要是数组,就一定有 length 属性。该属性是一个动态的值,等于键名中最大整数加 1 。

数组的数字键不需要连续。

length属性是可写的。意味着 增加 or 删除 数组整数键内容。清除数组的一个有效方法,就是将 length 属性设为 0 。

var arr = [ 'a', 'b', 'c' ];

arr.length = 0;
arr // []
var a = ['a'];

a.length = 3;
a[1] // undefined

如果人为设置 length 为不合法的值,JavaScript 会报错。

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

var a = [];

a['p'] = 'abc';
a.length // 0

a[2.1] = 'abc';
a.length // 0

如果数组的键名是添加超出范围的数值,该键名会自动转为字符串。

var arr = [];
arr[-1] = 'a';
arr[Math.pow(2, 32)] = 'b';

arr.length // 0
arr[-1] //"a"
arr[4294967296] // "b"

上面代码中,我们为数组 arr 添加了两个不合法的数字键,结果 length 属性没有发生变化。这些数字键都变成了字符串键名。最后两行之所以会取到值,是因为取键值时,数字键名会默认转为字符串。

4、in 运算符

检查某个键名是否存在的运算符 in ,适用于对象,也适用于数组。

注意,如果数组的某个位置是空位,in 运算符返回 false 。

var arr = [];
arr[100] = 'a';

100 in arr //true
1 in arr /false

上面代码中,数组 arr  只有一个成员 arr[100], 其他位置的键名都会返回 false 。

5、for...in 循环和数组的遍历

for...in 循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊的对象。但是,for...in 不仅会遍历数组所有的数字键,还会遍历非数字键。

var a = [1, 2, 3];
a.foo = true;

for(var key in a){
  console.log(key);
}
//0
//1
//2
//foo

上面代码在遍历数组时,也遍历到了非整数键 foo 。所以,不推荐使用 for...in 遍历数组

数组遍历可以考虑使用 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 (i--){
  console.log(a[i]);
}

6、数组的空位

当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)。

var  a = [1, , 1];
a.length //3

上面代码表明,数组的空位不影响 length 属性。

需要注意的是,如果最后一个元素后面有逗号,并不会产生空位。也就是说,有没有这个逗号,结果是一样的。

数组的空位可以读取,返回 undefined 。

使用 delete 命令删除一个数组成员,会形成空位,并且不会影响 length 属性。

var a = [1, 2, 3];
delete a[1];

a[1]//undefined
a.length //3

上面代码用 delete 命令删除了数组的第二个元素,这个位置就形成了空位,但是对 lenght 属性没有影响。也就是说,length 属性不过滤空位。所以,使用 length 属性进行数组遍历,一定要非常小心。

数组的某个位置是空位,与某个位置是 undefined ,是不一样的。如果是空位,使用数组的 forEach 方法、for...in结构、以及 Object.keys 方法进行遍历,空位都会被跳过。如果某个位置是 undefined ,遍历的时候就不会被跳过。

7、类似数组的对象

如果一个对象的所有键名都是正整数或零,并且有 length 属性,那么这个对象都很像数组,语法上称为“类似数组的对象”(array-like object)。

var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

obj[0] // 'a'
obj[1] // 'b'
obj.length //3
obj.push('d') // TypeError: obj.push is not a fucntion

上面代码中,对象 obj 就是一个类似数组的对象。但是,“类似数组的对象”并不是数组,因为他们不具备数组特有的方法。对象 obj 没有数组的 push 方法,使用该方法就会报错。

“类似数组的对象”的根本特征,就是具有 length 属性。只要有 length 属性,就可以认为这个对象类似于数组。但是有一个问题,这种 length 属性不是动态值,不会随着成员的变化而变化。

var obj = {
  length:0
};
obj[3] = 'd';
obj.length //0

上面代码为对象 obj 添加了一个数字键,但是 length 属性没变。这就说明了 obj 不是数组。

典型的“类似数组的对象”是函数 arguments 对象,以及大多数 DOM元素集,还有字符串。

//arguments对象
function args(){ return arguments }
var arrayLike = args('a', 'b');

arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false

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

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

上面代码包含三个例子,它们都不是数组(instanceof 运算符返回 false),但是看上去都非常像数组。

数组的 slice 方法可以将“类似数组的对象”变成真正的数组。

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

除了转为真正的数组,“类似数组的对象”还有一个办法可以使用数组的方法,就是通过 call() 把数组的方法放到对象上面。

function print(value, index){
  console.log(index + ' : ' + value);
}

Array.prototype.forEach.call(arrayLike, print);

上面代码中,arrayLike 代表一个类似数组的对象,本来是不可以使用数组的 forEach() 方法的,但是通过 call() ,可以把 forEach() 嫁接到 arrayLIke 上面调用。

下面的例子就是通过这种方法,在 arguments 对象上面调用 forEach 方法。

//forEach 方法
function logArgs(){
  Array.prototype.forEach.call(arguments, function(elem, i){
    console.log(i + '. ' + elem);
  });
}

//等同于 for 循环
function logArgs(){
  for(var i = 0; i<arguments.length; i++){
    console.log(i + '. ' + arguments[i]);
  }
}

字符串也是类似数组的对象,所以也可以用Array.prototype.forEach.call 遍历。

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

注意,这种方法比自己使用数组原生 forEach 要慢,所以最好还是先将“类似数组的对象”转为真正的数组,然后再直接调用数组的 forEach 方法。

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

 

 

摘自:https://wangdoc.com/javascript/types/array.html

posted @ 2018-09-17 15:56  cc7777  阅读(307)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3