-
Notifications
You must be signed in to change notification settings - Fork 0
第七章:数组
####1. javascript数组是无类型的:数组元素可以是任意类型,并且同一个数组中的不同元素也可能是不同的类型
####2. 数组的元素可以是对象,也可以是其他数组
####3. javascript数组是动态的:根据需要它们会增长或缩减
####4. javascript数组可能是稀疏的;针对非稀疏数组length即为数组的元素个数,针对稀疏数组length大于元素的个数
####5. 创建数组:可用数组直接量方式;new Array() 或 new Array(n) n为数组的长度
####6. 所有的索引都是属性名,但只有0到4294967294之间的整数属性名才是数组的索引
####7. 数组索引仅仅是对象属性名的一种特殊类型,故javascript数组没有越界错误的概念
####8. ES5中数组可以定义元素的getter和setter方法
####9. 稀疏数组就是包含从0开始的不连续索引的数组 例: a = new Array(5); //数组没有元素,但是a.length为5 a = []; //创建length为0的空数组 a[1000] = 3; //赋值添加一个元素,设置length为1001
以上创建的都是稀疏数组
####10. 可用in
运算符检测某个索引处是不存在元素,还是存在但值为undefined.索引值类似于属性名
例: a = new Array(3);
0 in a //false 表示没有元素,true表示有元素
####11. 每个数组有一个length属性,一般而言这个属性使数组区别于常规的javascript对象
####12. 数组有两个特殊行为
-
为一个数组元素赋值,它的索引i大于或等于现有数组的长度时,length属性的值将设为
i+1
-
设置length属性为一个小于当前长度的非负整数n时,当前数组中那些索引值大于或等于n的元素将从数组中删除
例: var a = [1,2,3,4,5]; //初始化有五个元素的数组 a.length = 3; //现在a为[1,2,3] a.length = 0; //删除a中所有元素 现在a为[] a.length = 5; //length为5,但没有元素 就像 new Array(5)
####13. 可用Object.defineProperty()让数组的length属性变为只读的 例: a = [1,2,3]; Object.defineProperty(a, "length", {writable: false}); //让length为只读 a.length = 0; //a不会改变 a.length // 3
####14. 可以像删除对象属性一样使用delete运算符来删除数组元素 例: a = [1,2,3]; delete a[1]; //a在索引1处不在有元素 1 in a; //fasle 索引1并未在数组中定义(因为删除了) a.length; //delete运算符不影响数组的长度
####15. 从数组中删除元素,数组就会变成稀疏数组
####16. ES5中新增的数组方法中函数参数的参数一般顺序为 数组元素, 元素索引,数组本身(元素索引和数组本身是可选参数)
####17. ES5中,判断一个未知对象是否为数组非常有用。
在ES5中用方法Array.isArray()
例: Array.isArray([]); //true
Array.isArray({}); //false
ES3中定义如下方法用以判定
var isArray = Function.isArray || function(o){
return typeof o === "object" && Object.prototype.toString.call(o) === "[object Array]";
}
####18. javascript数组独有的特性
- 当有新的元素添加到数组中时,自动更新数组的length属性
- 设置length为一个较小的值将截断数组
- 从Array.prototype中继承了一些有用的方法
- 其类属性为 "Array"
####19. 检测类数组的对象 //判断o是否是一个类数组对象 function isArrayLike(o){ if(o && //o非null,undefined typeof o === "object" && //o是对象 isFinite(o.length) && //o.length是有限数值 o.length >= 0 && //o.length是非负值 o.length === Math.floor(o.length) && //o.length是整数 o.length < 4294967294) //o.length小于4294967294 return true; else return false; }
部分数组方法的静态函数版本
Array.join = Array.join || function(a, sep){
return Array.prototype.join.call(a,sep);
}
Array.slice = Array.slice || function(a, from, to){
return Array.prototype.slice.call(a, from, to);
}
Array.map = Array.map || function(a, f, thisArg){
return Array.prototype.map.call(a, f, thisArg);
}
####20. 字符串是不可变值,故将其当数组看待时,它们是只读的。用数组方法来修改字符串会导致错误且出错时没有提示
####21. javascript中数组对象的方法
1.join()和split()
将数组的元素转化成字符串并连接在一起,默认使用逗号作为连接符,也可自定义如下例。split() 是join()的逆过程。都不会修改原值。
例:var a = [1,2,3];
a.join(); //"1,2,3"
a.join(" "); //"1 2 3"
a.join(""); //"123"
var b = new Array(10); //长度为10的空数组
b.join('='); // "=========="
var s = "z,h,r,m,g,h,g";
s.split(); //["z,h,r,m,g,h,g"]
s.split(","); //["z", "h", "r", "m", "g", "h", "g"]
2.reverse()
将数组顺序翻转,会修改数组本身,而不是返回新的数组。
例:var a = [1,2,3];
a.reverse().join(); //"3,2,1"
a的值是[3,2,1]
3.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 }); //[1111, 222, 33, 4] 按数值顺序从大到小
var b = ['ant','Bug','cat','Dog'];
b.sort(); //["Bug", "Dog", "ant", "cat"] //按照ASCII顺序 排序
b.sort(function(s,t){ //不区分大小写 按字母顺序排序
var a = s.toLowerCase();
var b = t.toLowerCase();
if( a < b ) return -1;
if( a > b ) return 1;
return 0;
});
结果:["ant", "Bug", "cat", "Dog"]
4.concat()
数组合并,将已知数组与其他数组合并,执行结果会返回一个新数组,不修改原来调用concat()的数组。
例:var a = [1,2,3];
a.concat(4,5); // [1,2,3,4,5]
a.concat([4,5]); // [1,2,3,4,5]
a.concat([4,5],[6,7]); // [1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]); // [1,2,3,4,5,[6,7]]
a依旧是 [1,2,3] ,没有被修改。
5.slice()
返回一个数组片段或子数组。不会修改调用数组。包含两个参数:第一个是起始位置,第二个是终止位置。返回结果不包含终止位置的元素。
例:var a = [1,2,3,4,5];
a.slice(0,3); //[1,2,3]
a.slice(3); //[4,5] 只传一个参数表示从参数指定的位置开始直到数组结尾
a.slice(1,-1); //[2,3,4] 位置-1表示的是元素5 因为位置0表示的是元素1。
a.slice(-3,-2); //[3]
6.splice()
从数组中删除元素,插入元素到数组中。或者同时完成以上两种操作。会对原数组做出修改。第一个参数指定了插入或删除元素的起始位置,第二个参数指定的是从数组中删除元素的个数。如果省去第二个参数表示删除从指定的起始位置开始到数组结尾的全部元素。splice()返回值是由被删除元素组成的数组。
例:var a = [1,2,3,4,5,6,7,8]
//删除位置4也就是元素5(包括5)之后的所有元素
a.splice(4) //返回值 [5,6,7,8] a的值[1,2,3,4]
a.splice(1,2) //返回值 [2,3] a的值[1,4]
a.splice(1,1) //返回值 [4] a的值[1]
splice() 前两个参数指定了需要删除的数组元素,紧随其后的任意个数参数指定了需要插入到数组中的元素。插入的位置是第一个参数指定的。
例:var b = ["m","l","x","b","r","j"]
//在位置3处不删除任何元素,插入5,2,1三个元素
b.splice(3,0,5,2,1) //返回值 []
b的值["m", "l", "x", 5, 2, 1, "b", "r", "j"]
var c = ["m","l","x","AI","b","r","j"]
//删除从位置3开始的一个元素即 "AI" 插入5,2,1三个元素
c.splice(3,1,5,2,1) //返回值 ["AI"]
b的值["m", "l", "x", 5, 2, 1, "b", "r", "j"]
7.push()和pop()
从数组末尾存入(push())或弹出(pop())元素,push()返回新数组的长度,pop()返回弹出的元素并从数组中删除该元素。
例: var stack = []; //stack: []
stack.push(1,2); //stack: [1,2] 返回 2
stack.pop(); //stack: [1] 返回 2
stack.push(3); //stack: [1,3] 返回 2
stack.pop(); //stack: [1] 返回 3
stack.push([4,5]); //stack: [1,[4,5]] 返回 2
stack.pop(); //stack: [1] 返回 [4,5]
stack.pop(); //stack: [] 返回 1
8.unshift()和shift()
从数组开始位置存入(unshift())或弹出(shift())元素,unshift()返回新数组的长度,shift()删除数组的第一个元素并将其返回。
例:var a = []; //a: []
a.unshift(1); //a: [1] 返回 1
a.unshift("a"); //a: ["a",1] 返回 2
a.shift();//a: [1] 返回 "a"
a.unshift(7,[4,5]); //a: [7,[4,5],1] 返回 3 注意:此处是参数作为整体存入的
a.shift();//a: [[4,5],1] 返回 7
a.shift();//a: [1] 返回 [4,5]
a.shift();//a: [] 返回 1
####22. EMACScript 5中Array对象新增的方法
1.forEach()
forEach()方法从头至尾遍历数组。forEach()方法第一个参数是一个函数【该函数有三个参数:数组元素,元素的索引,数组本身。如果只关心数组元素的值可以忽略额外的两个参数】
例: var a = [1,2,3,4,5];
//遍历并输出数组中的元素
a.forEach(function(v){
console.log(v);
});
//对数组中的元素求和
var sum = 0;
a.forEach(function(v){
sum += v;
});
//数组元素加1
a.forEach(function(v,i,a){
a[i]=v+1
});
传递的函数修改了数组 a现在是[2,3,4,5,6]
2.map()
map()方法,同样也是传递一个函数(参数为数组的元素)作为参数,返回一个数组【经过函数处的过的数组】
例: var a = [1,2,3,4,5]
var b = a.map(function(v){
return v+2;
});
b的值是[3,4,5,6,7]
a的值不变还是[1,2,3,4,5]
3.filter()
filter()方法返回一个数组是调用数组的一个子集,同样也是传递一个函数作为参数。该函数的作用就是作为过滤条件(即起逻辑判断作用),其返回值是布尔值。不会修改原数组。具体见下例:
var a = [5,4,3,2,1]
//返回大于3的元素
var b = a.filter(function(v){
return v>3;
});
b的值是[5,4]
a的值是[5,4,3,2,1]
//返回索引为偶数的元素
var c = a.filter(function(v,i){
return i%2==0;
});
c 的值是[5,3,1]
a的值是[5,4,3,2,1]
4.every()和some()
every()和some()是对数组做逻辑判定的。传递一个函数作为参数即为判断条件。every():数组中所有元素满足条件 返回ture。some():数组中存在满足条件的元素 返回ture。
例:var a = [3,5,6,2,7];
a.every(function(x){ return x>1 }); //true
a.every(function(x){ return x>3 }); //false
a.some(function(x){ return x>5 }); //true
//探测数组中是否含有非数值元素
a.some(isNaN); //false 表示不存在非数值元素 isNaN是内置函数
5.reduce()和reduceRight()
reduce()和reduceRight()方法使用指定的函数将数组元素进行组合,生成单个值。
例:var a = [1,2,3,4,5];
//数组求和
var sum = a.reduce(function(x,y){return x+y}, 0);
//数组求积
var p = a.reduce(function(x,y){return x×y}, 1);
//数组求最大值
var max = a.reduce(function(x,y){return (x>y)?x:y});
reduce()方法需要两个参数。第一个是执行化简操作的函数。化简函数的作用就是用某种方法把两个值组合或化简为一个值并返回化简后的值。第二个参数是传递给第一参数(即函数)的初始值。第二个参数是可选的。当不指定初始值的时候,默认使用数组的第一个元素作为初始值。
reduceRight()的工作原理和reduce()是一样的,不同的是它按照数组索引从高到低(从右到左)处理数组。
6.indexOf()和lastIndexOf()
indexOf()和lastIndexOf()搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引如果没有找到就返回-1。indexOf()从头至尾搜索。lastIndexOf()则反向搜索。indexOf()和lastIndexOf()可以接受两个参数,第一个是要查找的值,第二个是可选的:它指定一个索引,表示从该索引处开始搜索
例:
var a = [1,0,2,3,2,1];
a.indexOf(1); // 0 a[0]是1
a.lastIndexOf(1); // 5 a[5]是1
a.indexOf(4); // -1 没有值为4的元素
//在数组a中查找所有出现的x,返回x的所有索引构成的数组。
function findAll(a,x){
var results = [];
var pos = 0;
while(pos < a.length){
pos = a.indexOf(x,pos);
if(pos===-1) break;
results.push(pos);
pos++
}
return results;
}
by @zhulinpinyu 👍