7.01 - what is array?
简单来说,数组是一个
数字序列号与内容对应的容器
类似于一个班级中(数组)学号(序列号)与学生(序列号对应的内容)的关系,不同的是数组的内容可以是任意的数据类型
数组的定义方式
Array对象:通过实例化 JavaScript 原生的内置 Array 构造函数产生一个数组
var arr = new Array(3); // 定义一个长度为3的数组
console.log(arr); // [empty × 3]
字面量:[]
var arr = [];
arr.length = 3;
console.log(arr);// [empty × 3]
数组的特性
数组是一个,键为数字的特殊的对象
var arr = [];
console.log(typeof arr);// object
// 通过Array.isArray()方法判断一个对象是不是数组
console.log(Array.isArray(arr)); // true
// 通过 instanceof关键字
console.log(arr instanceof Array);
数组的长度:array.length
固定长度:通过数组的length属性,或者通过构造函数创建数组的时候可以限定数组的长度
动态长度:没有固定长度的时候,数组的长度是由内容决定的
序列从0开始:数组的序列号是从0开始的所以最后一个成员的的序列号为长度减1
数组的成员可以是任意数据类型,包括另外一个数组或者对象
var arr = [ 1 , "2" , function(){} , [/a/] , {a:1}];
console.log(arr[3]); // [/a/]
7.02 - 数组的读写
获取数组成员
通过下标获取
var arr = ['a','b','c','d'];
console.log(arr[0]); // 'a'
for 遍历
var arr = ['a','b','c','d'];
for(var i=0;i<arr.length;i++){
console.log( arr[i] ); // 'a' 'b' 'c' 'd'
}
array.forEach(fn)
var arr = ['a','b','c','d'];
arr.forEach(function(a,b,c){
console.log(a); // 'a' 'b' 'c' 'd'
console.log(b); // 0 1 2 3
console.log(c); // ['a','b','c','d']
});
设置数组成员
通过下标设置
var arr = ['a','b','c','d'];
arr[1] = "hello world!!";
console.log(arr);// ['a','hello world!!','c','d']
通过下标添加成员
var arr = ['a','b','c','d'];
arr[4] = "hello world!!";
console.log(arr);// ['a','b','c','d','hello world!!']
删除数组的成员
delete
delete 删除的成员会在原来的位置留下一个空位(empty),并不会改变原数组的长度
var arr = ['a','b','c','d'];
delete arr[1];
console.log(arr);// ['a',empty,'c','d']
数组方法
splice()
pop()
shift()
7.03 - 数组的方法
成员操作类
方法 | 功能 |
---|---|
push(param) | 往后加:向数组末尾添加元素 param (arr[arr.length]=param) |
unshift(param) | 往前加:向数组开始添加元素 param([param].concat(array)) |
pop() | 删后边:从数组的末尾删除元素,并返回 |
shift() | 删前边:从数组的前端删除元素,并返回 |
slice(s,e) | 复制:复制从序列号s到e的数组中成员,默认为0~末尾,不会改变原数组 |
splice(s,e[,alt,...]) | 截取与替换:截取从序列号s开始的e个数组中成员,默认为0~末尾,替换为alt,改变原数组,返回截取到的成员 |
concat(array) | 合并:合并数组,从末尾添加参数数组中的元素到当前数组,返回一个新数组,不会改变原数组 |
reverse() | 反转:反转数组,改变原数组 |
sort( [fn] ) | 排序:按照(ASCII值排列数组),可以传入一个函数参数改变排列方式,改变原数组 |
数组工具类
方法 | 功能 |
---|---|
join( [string] ) | 拼字符串:将数组的成员以传入的参数的字符串进行拼,返回拼接完成的字符串 |
indexOf( param [,index] ) | 第一次出现:返回参数 param 在数组中第一次出现的位置,没有则返回 -1,可选起始索引值参数 |
lastIndexOf( param ) | 最后一次出现:返回参数 param 在数组中最后出现的位置,没有则返回 -1 |
toString() | 变字符串:返回数组的字符串形式 |
some( fn ) | 某个对不对:判断数组中的是否有某一个 元素符合某个条件,返回一个布尔值 |
every( fn ) | 全部对不对:判断数组中的是否所有 元素都符合某个条件,返回一个布尔值 |
find( fn ) | 要找谁:返回第一个符合条件的元素 |
findIndex( fn ) | 要找谁在那:返回第一个符合条件的元素的序列号 |
遍历类
方法 | 功能 |
---|---|
forEach( fn [,point] ) | 找人:遍历数组,传递一个方法参数得到每个遍历成员,可选内部this指向的参数 |
filter( fn [,point]) | 挑人:遍历数组,筛选出所有符合条件的元素,返回一个新的数组,可选内部this指向的参数 |
reduce( fn [,int]) | 合体:迭代, 依次处理数组的每个成员,最终累计为一个值,并且返回这个值 |
map( fn [,point] ) | 都打一顿:遍历数组的每个成员,以fn的返回值组成一个新的数组,不会改变原数组 |
7.04 - 类数组对象
和数组一样,键名都是大于等于0的正整数,并且拥有length属性的对象被称之为类数组对象,比如:字符串,dom节点对象,arguments参数列表等等
类数组对象与数组的对比
类数组不能直接使用数组方法
var arrayLikeObj = {
0 : "a",
1 : "b",
2 : "c",
3 : "d",
length : 4
};
// Error
/*
arrayLikeObj.forEach(function(a){
console.log(a);
});
*/
// 但是可以通过call方法使用
Array.prototype.forEach.call(arrayLikeObj,function(a){
console.log(a);
});
类数组对象的length属性不是动态的
可以通过数组的slice方法将大部分类数组转变成数组
var str = "abcdef";
var arr = Array.prototype.slice.call(str);
console.log(arr);// [a,b,c,d,e,f]
类数组转变成数组的方法
遍历添加
<div>老大</div> <div>老二</div> <div>三儿</div> <div>四儿</div> <script> function changeArr(arrayLike){ var arr = []; for(var i=0,l=arrayLike.length;i<l;i++){ arr.push(dDiv[i]); } return arr; } Array.isArray(changeArr(document.getElementsByTagName("div"))); // true </script>
arrray.selice.call(arrayLike)
<div>老大</div>
<div>老二</div>
<div>三儿</div>
<div>四儿</div>
<script>
function changeArr(arrayLike){
return Array.prototype.slice.call(arrayLike));
}
Array.isArray(changeArr(document.getElementsByTagName("div"))); // true
</script>
ES6(兼容问题,了解)
<div>老大</div>
<div>老二</div>
<div>三儿</div>
<div>四</div>
<script>
// Array.form() 方法
function changeArrForm(arrayLike){
return Array.form(arrayLike);
}
// ... 不定参
function changeArrArgments(arrayLike){
return [arrayLike];
}
Array.isArray(changeArrForm(document.getElementsByTagName("div"))); // true
Array.isArray(changeArrArgments(document.getElementsByTagName("div"))); // true
</script>
7.05 - 数组方法的使用技巧
getClass 兼容
循环遍历每个标签的每个类名进行判断
function getClass(name,parent){
parent = parent || document;
if(typeof name !== "string" || typeof paent !== "object")return;
if(parent.getElementsByClassName){
return parent.getElementsByClassName(name);
}else{
var
all = parent.getElementsByTagName("*"),
arr = [],
cName = cNames = "";
for(var i=0,lenI=all.length;i<lenI;i++){
cName = all[i].className;
if(cName){
cNames = cName.split(" ");
for(var j=0,lenJ=cNames.length;j<lenJ;j++){
if(cNames[j] === name){
arr.push(all[i]);
break;
}
}
}
}
return arr;
}
}
filter( 伪兼容,因为filter方法本身就不兼容 )
function getClass(name,parent){
parent = parent || document;
if(typeof name !== "string" && typeof paent !== "object")return;
if(parent.getElementsByClassName){
return parent.getElementsByClassName(name);
}else{
var
all = [].slice.call(parent.getElementsByTagName("*")),
cName = "";
return all.filter(function(item){
cName = item.className;
return cName?cName.split(" ").indexOf(name) !== -1:false;
});
}
}
类名操作
添加类名
function addClass(addNames,dom){
var cName = dom.className.trim();
if(!cName){dom.className = addNames;return;};
var
cNameArr = cName.split(" "),
addNameArr = addNames.trim().split(" "),
len = cNameArr.length,
addLen = addNameArr.length;
if(len === 1 && addLen === 1 && cName !== addNames){
dom.className += " " + addNames;
}else{
// 筛选剔除添加项的重复项
var str = addNameArr.filter(function(item){
return cNameArr.indexOf(item) === -1?item:false;
}).join(" ");
dom.className += str?" "+str:"";
// 遍历剔除添加项的重复项
// for(var i=0;i<len;i++){
// for(var j=0;j<addNameArr.length;j++){
// if(cNameArr[i] === addNameArr[j]){
// addNameArr.splice(j,1);
// break;
// }
// }
// }
// var str = addNameArr.join(" ")
// dom.className += str?" "+str:"";
// 全部添加然后去重
// var cArr = cNameArr.concat(addNameArr);
// dom.className = cArr.filter(function(item,ind){
// return cArr.indexOf(item) === ind;
// }).join(" ");
// 对象属性的唯一
// var nameJson = {};
// var cArr = cNameArr.concat(addNameArr);
// cArr.forEach(function(item){
// nameJson[item] = null;
// });
// dom.className = Object.keys(nameJson).join(" ");
// 正则的方式
// addNameArr.forEach( function(item, index) {
// cName += new RegExp("(?<=^|\\s)"+item+"(\\s|$)+").test(cName)?"":" "+item;
// });
// dom.className = cName;
}
}
删除类名
function removeClass(reNames,dom){
var cName = dom.className.trim();
if(!cName)return;
var
cNameArr = cName.split(" "),
reNameArr = reNames.trim().split(" "),
len = cNameArr.length,
reLen = reNameArr.length;
// 遍历剔除
for(var i=0;i<reLen;i++){
for(var j=0;j<cNameArr.length;j++){
if(reNameArr[i] === cNameArr[j]){
cNameArr.splice(j,1);
}
}
}
dom.className = cNameArr.join(" ");
// 筛选剔除
// dom.className = cNameArr.filter(function(item,index){
// return reNameArr.indexOf(item) === -1;
// }).join(" ");
// 正则
// reNameArr.forEach( function(item, index) {
// cName = cName.replace(new RegExp("(?<=^|\\s)"+item+"(\\s|$)+"),"");
// });
// dom.className = cName;
}
自动检测
function toggleCass(cNames,dom){
var cName = dom.className.trim();
if(!cName){dom.className = cNames;return;};
var
cNameArr = cName.split(" "),
addNameArr = cNames.trim().split(" "),
len = cNameArr.length,
addLen = addNameArr.length;
// 遍历判断
var off;
for(var i=0;i<addLen;i++){
off = true;
for(var j=cNameArr.length-1;j>=0;j--){
if(addNameArr[i] === cNameArr[j]){
cNameArr.splice(j,1);
off = false;
}
}
if(off){
cNameArr.push(addNameArr[i]);
}
}
dom.className = cNameArr.join(" ");
// 筛选
//dom.className = cNameArr.filter(function(item){
//var ind = addNameArr.indexOf(item);
//return ind === -1?true:(addNameArr.splice(ind,1),false);
//}).concat(addNameArr).join(" ");
}
筛选排序
价格排序
<div id="box">
<p>100</p>
<p>20</p>
<p>310</p>
<p>30</p>
</div>
<script>
var
dBox = document.getElementById("box"),
dP = dBox.getElementsByTagName("p");
var dPArr = [].slice.call(dP);
var off = false,_dPArr;
document.onclick = function(){
_dPArr = dPArr.sort(function(a,b){
if(off)a = [b,b=a][0];
return b.innerText*1 - a.innerText*1;
});
off= !off;
_dPArr.forEach((item)=>{
dBox.appendChild(item);
})
}
</script>
数组去重
遍历删除重复
var arr = [1,1,1,2,2,3,3,1];
function unique(arr){
if(arr instanceof Array){
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;){
arr[i] === arr[j]?arr.splice(j,1):j++;
}
}
}
return arr;
}
遍历添加不重复的项
function unique(arr){
if(arr instanceof Array){
var
arr1 = [arr[0]],
len = arr.length,
off;
for(var i=1;i<len;i++){
off = true;
for(var j=0;j<arr1.length;j++){
if(arr[i] === arr1[j]){
off=false;
break;
}
}
if(off)arr1.push(arr[i]);
}
return arr1;
}
}
排序后添加至新数组进行比较
会打乱数组的顺序
无法让对象元素进行去重
因为sort的限制无法区分数字的字符串
function unique(arr){
if(arr instanceof Array){
arr.sort();
var arr1 = [arr[0]];
for(var i=1,len = arr.length;i<len;i++){
if(arr[i]!=arr1[arr1.length-1])arr1.push(arr[i]);
}
return arr1;
}
}
排序后比较相邻元素
会打乱数组的顺序
无法让对象元素进行去重
因为sort的限制无法区分数字的字符串
function unique(arr){
// 排序
arr.sort();
var item = arr[0];
var _arr = [];
// 循环添加相邻的项
while(item){
_arr.push(item);
item = arr[ arr.lastIndexOf(item)+1 ];
}
return _arr;
}
indexOf 判断
function unique(arr){
if(arr instanceof Array){
var _arr = [arr[0]];
for(var i=1,len=arr.length;i<len;i++)
if(_arr.indexOf(arr[i]) === -1)_arr.push(arr[i]);
return _arr;
}
}
序列号的唯一性
// filter
function unique(arr){
if(arr instanceof Array){
return arr.filter(function(item,index,Arr){
return Arr.indexOf(item) === index;
});
}
}
// 循环
function unique(arr){
if(arr instanceof Array){
var _arr = [];
for(var i=0,len=arr.length;i<len;i++){
if(arr.indexOf(arr[i]) === i){
_arr.push(arr[i]);
}
}
return _arr;
}
}
Set( ES6 )
function unique(arr){
if(arr instanceof Array){
return Array.from(new Set(arr));
}
}
复制数组
遍历添加
var arr = [1,2,3,4,5];
function copyArr(arr){
var _arr;
arr.forEach(function(item){
_arr.push(item);
});
return _arr;
}
slice()
var arr = [1,2,3,4,5];
function copyArr(arr){
return arr.slice(0);
}
其他技巧
一个等同 push() 技巧
var arr = [1,2,3,4,5,6];
var _arr = [];
arr.forEach(function(item){
// _arr.push(item)
_arr[_arr.length] = item;
});
console.log(_arr); // [1,2,3,4,5,6]
一个等同 unshift() 的技巧
var arr = [1,2,3,4,5,6];
var _arr = [];
arr.forEach(function(item){
// _arr.unshift(item)
_arr = [item].concat(_arr);
});
console.log(_arr); // [6,5,4,3,2,1]