数组
数组是一段线性分配的内存,它通过整数计算偏移并访问其中的元素。
数组字面量
var numbers=['zero','one','two','three','four','five','six'];
对象字面量:
var numbers_object={
'1':'one',
'2':'two',
'3':'three',
'4':'four',
'5':'five',
'6':'six'
};
数组字面量和数组对象字面量这两者有着显著的区别。这两者的区别是numbers继承自Array.prototype,而numbers_object继承自object.prototype。所以numbers继承了大量有用的方法(push,slice等),同时numbers有一个length属性。
console.log(numbers); //(7) ["zero", "one", "two", "three", "four", "five", "six", b: "b"]
console.log(numbers.indexOf('b')); //-1
console.log(numbers_object);//{1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six"}
console.log(numbers_object[1]); //one
// console.log(numbers_object.1); //error
探索发现:
- 通过numbers[‘b’]=’b’添加进入数组的元素,不会使得数组的length增加。同时也没有数组的方法。
- 对象的本质是数组的一种特殊的形式,数组的下标可以是两种形式:a[1] a[‘b’],第二种用字符串当下标的数组我们一般称之为hash数组,也是对象的解构的来源,对象其实也就是hash数组,它的特点就是下标不是数字,所以,一般情况下,不建议使用数字作为对象的属性名,使用纯数字的时候,我们不可以通过.运算符来取值。这也就是我们输出numbers_object.1报错的原因。
长度
length属性是这个数组的最大整数属性名加1。它不一定等于数组里的属性的个数。就像添加array[“a”]=”a”;数组的length并不会加一。
var arr=[];
arr[10]='Mike';
console.log(arr); //(11) [undefined × 10, "Mike"]
arr['12']='Lili';
console.log(arr);//(13) [undefined × 10, "Mike", undefined × 1, "Lili"]
arr['a']='a';
console.log(arr); //(13) [undefined × 10, "Mike", undefined × 1, "Lili", a: "a"]
arr.length=3;
console.log(arr); //(3) [undefined × 3, a: "a"]
var new_numbers=['zero','one','two','three','four','five','six'];
new_numbers.length=3;
console.log(new_numbers); //(3)['zero','one','two']
探索发现:
- 我们通过设定length属性也可以来删除数组元素。
- arr[‘a’]=’a’;,这样并不增加数组的length。
删除
js中的数组其实就是对象,所以delete运算符可以用来从数组中删除元素。
var arr1=['zero','one','two','three','four','five'];
delete arr1[2];
console.log(arr1);//(6) ["zero", "one", undefined × 1, "three", "four", "five"]
arr1.splice(2,1);
console.log(arr1);//(5) ["zero", "one", "three", "four", "five"]
探索发现:
- 通过delete方法来删除数组的元素的时候,被删除的元素会保留它最初的属性undefined。
枚举
javascript的数组就是对象。所以可以用for in来遍历一个数组的所有的属性,然而for in不能保证属性的顺序,因此我们一般用for进行遍历。
for(var value in arr1){
console.log(arr1[value]);
} //zero one three four five
for(var i=0;i<arr1.length;i++){
console.log(arr1[i]);
} //zero one three four five
探索发现:
- 在for in遍历中,我们必须使用arr1[value]来获取属性值,而不能使用arr1.value是因为:obj.value ===obj[‘value’],value是字符串,它其实是这样的:var obj={“name”:”Mike”} value===”name”;所以:obj[attr] ===obj[‘a’]。
容易混淆的地方
JavaScript本身对于数组和对象的区别是混乱的,我们通过定义自己的函数来判断该值是数组还是数组对象。
var is_array=function(value){
return value&&typeof value=='object'&&value.constructor===Array;
}
var is_array1=function(value){
return Object.prototype.toString.apply(value)=='[Object Array]';
}
方法
我们可通过给Array.prototype添加方法来给所有的数组添加方法。
Array.prototype.reduce=function(f,value){
for(var i=0;i<this.length;i++){
value=f(this[i],value);
}
return value;
}
function add(a,b){
return a+b;
}
var data=[1,2,3];
console.log(data.reduce(add,0)); //6
data.total=function(){
return this.reduce(add,0);
}
console.log(data.total());//6
指定初始值
JavaScript数组通常不会预置值,如果访问一个数组中不存在的值,将得到undefined。JavaScript没有多维数组,但是却支持元素为多数组的数组。
Array.dim=function(dimension,initial){
var a=[];
for(var i=0;i<dimension;i++){
a[i]=initial;
}
return a;
}
var myArr=Array.dim(10,0);
console.log(myArr); //(10) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
var mytrix=[
[0,1,2],
[3,4,5],
[6,7,8]
];
console.log(mytrix[2][1])//7
//为了创建一个二维数组或者说是数组的数组,我们必须自己去创建第二维的数组
for(var i=0;i<10;i++){
var my_array=new Array();
my_array[i]=[];
}
//用来构造矩阵的函数
Array.matrix=function(m,n,initial){
var a,mat=[];
for(var i=0;i<m;i++){
a=[];
for(var j=0;j<n;j++){
a[j]=initial;
}
mat[i]=a;
}
return mat;
}
//构造一个用0填充的4*4的矩阵
var myMatrix=Array.matrix(4,4,0);
console.log(myMatrix[3][3])//0
//用来构造一个单位矩阵
Array.identity=function(n){
var mat=Array.matrix(n,n,0);
for(var i=0;i<n;i++){
mat[i][i]=n;
}
return mat;
}
myMatrix=Array.identity(4);
console.log(myMatrix[3][3]);//4