第6章-数组
数组字面量 Array Literals
一个数组字面量是在一对方括号中包围零个或多个用逗号分隔的的值的表达式。数组字面量允许出现在任何表达式可以出现的地方,数组的第一个值将获得属性名'0',依此类推。JavaScript允许数组包含任意混合类型的值
1 var empty = []; 2 var numbers = [ 3 'zero','one','two','three','false','12' 4 ]; 5 6 empty[1]; //undefined 7 numbers[2]; //"two" 8 numbers.length; //6
长度 Length
JavaScript数组中的length是没有上界的,如果用大于当前length值的数字作为下标来储存值,那么数组就会被扩充来容纳这个元素。
1 var empty = []; 2 empty.length; //0 3 empty[100] = 'QQQ'; 4 empty.length; //101 5 //[]后置下标运算符把它所包含的表达式转换成一个字符串,如果该表达式有toString方法,就使用该方法的值 6 empty['100']; //QQQ
如果把length设小将导致所有下标大于等于新length的属性被删除
1 var numbers = [ 2 'zero','one','two','three','false','12' 3 ]; 4 numbers.length = 2; 5 console.log(numbers); //["zero", "one"]
删除 Delete
由于JavaScript的数组就是对象,所以delete运算符可以用来从数组中移除元素:
1 var numbers = [ 2 'zero','one','two','three','false','12' 3 ]; 4 delete numbers[2]; 5 console.log(numbers); //["zero", "one", 3: "three", 4: "false", 5: "12"] 6 numbers.length; //6
要删除数组中的一项有一个更好的办法splice方法,它接受两个参数即:数组中的一个序号和要删除的个数
1 numbers.splice(2,1); 2 console.log(numbers); //["zero", "one", "three", "false", "12"] 3 numbers.length; //5
枚举 Enumeration
for in 语句不太适用,它无法保证属性的顺序,而且从原型链中得到意外属性的问题依旧存在。这里最好只用for语句
容易混淆的地方 Confusion
在JavaScript编程中,一个常见的错误是在必须使用数组时使用了对象,或者在必须使用对象时使用了数组。其实规则很简单:当属性名是小二连续的整数时,应该使用数组,否则,使用对象。
JavaScript本身对于数组和对象的区别混乱的,typeof运算符报告数组的类型是'object'
JavaScript没有一个好的机制来区别数组和对象,我们可以通过定义自己的is_array函数来弥补这个缺陷:
1 var numbers = [ 2 'zero','one','two','three','false','12' 3 ]; 4 var is_array = function(value){ 5 return value && typeof value === 'object' && value.constructor === Array; 6 }; 7 8 is_array(numbers); //true
但是,它在识别从不同的窗口或帧里构造的数组是会失败,改进后的方法:
1 var is_array = function(value){ 2 return Object.prototype.toString.apply(value) === '[Object Array]'; 3 };
方法 Method
同样Array.prototype也可以被扩充。举例来说,假设我们想要给array增加一个方法,它允许我们队数组进行计算:
1 Function.prototype.method = function(name,func){ 2 this.prototype[name] = func; 3 return this; 4 }; 5 6 Array.method('reduce',function(f,value){ 7 var i; 8 for(i=0;i<this.length;i++){ 9 value = f(this[i],value); 10 } 11 return value; 12 }); 13 14 //创建一个数组 15 var data = [4,8,3,6,98,1]; 16 //定义两个简单的函数 17 var add = function(a,b){ 18 return a + b; 19 }; 20 var mult = function(a,b){ 21 return a * b; 22 }; 23 24 //调用reduce方法 25 var sum = data.reduce(add,0); //122 26 var product = data.reduce(mult,1); //56448 27 28 //因为数组就是对象,所以我们可以直接给一个单独的数组添加方法: 29 data.total = function(){ 30 return this.reduce(add,0); 31 };
之前的Object.cteate方法用在数组是没有意义的,因为它产生一个对象,而不是数组,它将会继承这个数组的值和方法,但是没有length属性
指定初始值 Dimensions
JavaScript的数组通常不会预置值。如果你访问一个不存在的元素,得到的是underfined。我们可以自己初始化数组。
1 Array.dim = function(dimension,initial){ 2 var a = [], i; 3 for(i=0;i<dimension;i++){ 4 a[i] = initial; 5 } 6 return a; 7 } 8 9 //创建一个包含10个0的数组 10 var myArray = Array.dim(10,0); 11 12 //JavaScript没有多维数组,但就像大多数类C语言一样,它支持元素为数组的数组: 13 var matrix = [ 14 [0,1,2], 15 [3,4,5], 16 [6,7,8] 17 ]; 18 matrix[2][1]; //7
为了创建一个二维数组,你必须去自己去创建那个第二维的数组:
1 for(i=0;i<n;i++){ 2 ma_array[i] = []; 3 } 4 //注意:Array.dim(n,[])在这里不能工作 5 //如果使用它,每个元素都指向同一个数组的引用,那后果不堪设想。
一个空的矩阵的每个单元都会拥有一个初始值undefined。我们可以初始化他们。
1 Array.matrix = function(m,n,initial){ 2 var a,i,j,mat = []; 3 for(i=0;i<m;i++){ 4 a = []; 5 for(j=0;j<n;j++){ 6 a[j] = initial; 7 } 8 mat[i] = a; 9 } 10 return mat; 11 } 12 13 //构建一个用0填充的4x4矩阵 14 var myMatrix = Array.matrix(4,4,0); 15 16 //用来构造一个单位矩阵的方法 17 18 Array.identity = function(n){ 19 var i,mat = Array.matrix(n,n,0); 20 for(i=0;i<n;i++){ 21 mat[i][i] = 1; 22 } 23 return mat; 24 }; 25 myMatrix = Array.identity(4);