javascript learning notes——array
把数组的笔记写完先
数组继承自Array.prototype中的属性,定义了一套丰富的数组操作函数,对于类数组对象同样有效。
数组是javascript对象的特殊形式,用数字引索来访问数组元素要比访问常规的对象属性快很多。
javascript数组的引索是从零开始的32位数值。对于稠密数组,length即是数组包含的元素个数。对于稀疏数值,length比所有元素的引索都要大。
创建数组
var a1 = [,,,];//这里只有两个元素,这里","被当做介绍符用。等于[undefined,undefined]
var a2 = new array(3);//数组中没有储存值,甚至数组的引索属性"0"、"1"都还没有定义。
0 in a1 //=>true
0 in a2 //=>false
当使用小于2³²的非负整数作为属性名时,数组会自动维护其length属性值。
如果一个数组继承了元素或是使用了元素的getter和setter方法,将会丢失数组快速引索的优势。访问这种数组元素的时间会与常规对象的查找时间相近。
数组的长度length
设置数组的length值可以删除特定位置之后的元素。
在ECMAScript 5中,可以用Object.defineProperty()让数组的length属性变成只读:
a=[1,2,3];
Object.defineProperty(a,"length",{writable:false});
a.length=0;//这里的length属性不会改变
如果让一个数组的元素不能配置configurable:false,就不能删除它,length属性值就不能设置为小于该元素的引索值。
数组元素的删除
a = [1,2,3];
delete a[1];//a在引索1的位置不再有元素
1 in a//false,删除数组元素和赋值undefined是类似的
a.length//3,delete操作不影响数组长度
如果从属猪中删除一个元素,这个数组就变成了稀疏数组。
对于一个数组元素使用delete操作不会修改其length属性的值,也不会将元素从高引索处移下来填充删除留下的空白。
数组的遍历
特别注意,ECMAScript 5规范允许for/in循环已不同的顺序遍历对象的属性。通常数组元素的遍历实现是升序的,但是不能保证一定是这样的。
常用的数组遍历方法:for/in,for,forEach,map
数组的方法:jion,reverse,sort,concat,slice,splice,pop,push,shift,unshift,toString,toLocaleString
sort:
//使用匿名函数定义排序规则
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;
});//反序
forEach:
var data = [1,2,3,4,5];
var sum = 0;
data.forEach(function(value){
sum += value;
});
sum//总和
data.forEach(function(v,i,a){
a[i] = v + 1;
});
data//=>[2,3,4,5,6]
map:
//map的函数调用方式和传递给forEach()的函数的调用方式一样,但是map函数返回的是新的数组,它不修改原数组。稀疏数组也一样返回。
a = [1,2,3];
b = a.map(function(v){
return v*v;
});//=>[1,4,9]
filter:
//根据判定函数返回原数组的子集,它会自动跳过稀疏数组中缺少的元素,返回稠密数组。
a = [5,4,3,2,1];
smallvalues = a.filter(function(v){
return x<3;
});//=>[2,1]
everyother = a.filter(function(v,i)){
return i%2!=0;
};//[5,3,1]
var dense = a.filter(function(){return true;});//可以用来压缩空缺
a = a.filter(function(x){return x!=undefined && x!=null;});//可以用来压缩空缺并删除undefined和null元素
every,some:
a = [1,2,3,4,5];
a.every(function(x){return x < 20;});//true,所有元素都小于20
a.every(function(x){return x%2==0;});//false,不是所有元素都是偶数
a.some(function(x){return x%2==0;});//true,存在有偶数
a.some(NaN);//false,不存在非数值元素
reduce,reduceRight:
//使用自定函数组合数组元素,生成单个值
var a = [1,2,3,4,5,6];
var sum = a.reduce(function(x,y){return x+y;}, 0);//求和
var product = a.reduce(function(x,y){return x*y;}, 1);//求积
var max = a.reduce(function(x,y){return (x>y)?x:y;});//求最大值
var objects = [{x:1},{y:2},{z:3}];
var merge = objects.reduce(union);//=>{x:1,y:2,z:3},union(x,y)函数合并两个集合
,
//反序
var a = [2,3,4];
//计算2^(3^4)。操作的优先级别是从左到右
var big = a.reduceRight(function(accumulator,value){
return Math.pow(value,accumulator);
});
,
//覆盖的顺序
var objects = [{x:1,a:1},{y:2,a:2},{z:3,a:3}];
var leftunion = objects.reduce(union);//{x:1,y:2,z:3,a:1}
var right = objecs.reduceRight(union);//{x:1,y:2,z:3,a:3}
indexOf,lastIndexOf
//检测对象是否是array
var isArray = Function.isArray || function(o){
return typeof o === "object" && Object.prototype.toString.call(o) === "[object Array]";
};
类数组对象
var a = {};
//添加一些属性,称为“类数组”
var i = 0;
while(i<10){
a[i] = i * i;
i++;
}
a.length = i;
//当成数组来遍历
var total = 0;
for (var j =0; j<a.length; j++){
total += a[j];
}
判断类数组对象
//判断o是否是一个类数组对象
//字符串和函数有length属性,但是他们
//可以用typeof检测将其排除。在客户端js中,DOM文本节点
//也有length属性,需要用额外的o.nodeType != 3将其排除
function isArrayLike(o){
if (o &&//非null、undefined
typeof o === "object" &&//是对象
isFinite(o.length) &&
o.length >= 0 &&
o.length === Math.floor(o.length) &&
o.length < Math.pow(2,32-2)){
return true;
}else{
return false;
}
}