开始本章之前,先给出上一节的答案,参考答案地址:
http://www.xiaotublog.com/demo.html?path=homework/03/index2
1.JS数组的三大特性
在JavaScript中,数组和其他编程语言中的数组有所不同。首先体现在,在一般的编程语言中,数组的索引只能是数字,而js数组中,它的索引可以是任意类型。比如,你可能会看到这样的代码:
var arr=[]; //新建一个数组 arr['name']='rose'; arr['age']=12; alert(arr['name']); alert(arr['age']);
这个例子说明,在js中,数组的索引不一定只能是数字,但是,如果用数字作为索引的话,效率无疑会比较高一点,它内部必然做了优化。Js数组除了这一点比较特殊之外,还有一个需要注意的地方,就是它可以是动态的。我们知道,在Java中,要使用数组,必须要先对其进行初始化,也就是说,我得先规定好,这个数组的容量是多大,然后,我才能使用这个数组。在使用的过程中,要时刻注意好,不能超出数组的容量。如果数组要扩容,不管怎样,我都只好重新申请一块空间,new一个新的数组,然后把老数组中的那部分,嫁接拷贝到新的数组里面去。这就是Java数组的扩容概念。而在js中,数组的扩容变得毫不费力,因为它本来就是动态的。所以,你往往会看到这样的代码:
var arr=[]; //新建一个数组,长度为0 arr[0]=100; //动态扩容,现在长度为1 arr[1]=200; //动态扩容,现在长度为2 alert(arr.length);
很好用吧,在这一点上,js数组是非常灵活的。最后,js数组就像一个篮子,随便你放什么都可以。小到一个数字,字符串,大到对象,函数,随便你放什么,都可以的。
var arr=[]; //新建一个数组,长度为0 arr[0]=100; //动态扩容,现在长度为1 arr[1]=200; //动态扩容,现在长度为2 arr[2]="我是一个字符串"; arr[3]=function(){ alert('哈哈'); }; alert(arr);
在索引为3的地方,我们放入了一个函数,还是那句话,我现在问,这个函数有没有打括号,是不是还没有。好的,既然没有打括号,那么这个函数就不会被执行。也就是说,这个函数目前来看,就是和数字,字符串差不多的东西,还没有什么攻击力!我们可以这样去调用它:
arr[3]();
这样应该很好理解吧。当然了,这里我不太愿意像背字典一样,把每一个细节都讲一遍,我觉得那样没有太大意义。就算现在你记住了,过一段时间你说不定又忘记了。还是那句话,通过不断地写,不断地写,持续不断地写项目,在项目中把这些知识点练起来,这才是你真正可以获得的。
2.给数组赋值
在上面的例子中,我们可以通过这样的方式给数组赋值:
var arr=[]; //新建一个数组,长度为0 arr[0]=100; //动态扩容,现在长度为1 arr[1]=200; //动态扩容,现在长度为2 arr[2]="我是一个字符串";
这就是给数组赋值的第一种方式,通过数组扩容的方式,即刻赋值。其实还有另一种方式,就是通过push方法来给数组赋值。我们用这种方式把上面的代码重写一遍,无非就是这样:
var arr=[]; //新建一个数组,长度为0 arr.push(100); //动态扩容,现在长度为1 arr.push(200); //动态扩容,现在长度为2 arr.push("我是一个字符串"); alert(arr);
这样是不是也可以呢?好,现在我就想要请问一下了,push是什么。你不要把它想得太复杂了,我就问你,它后面有没有括号,有,好的。什么东西可以打括号?是不是方法呀,只有方法才可以打括号,打了括号就是去把它执行掉了。接下来再问,什么东西可以调用方法,是不是对象呀?OK,那么我们写的这个:
var arr=[];
这个arr是什么,是不是一个对象呀?好的,理解了这一点就好办多了。其实在JS中,数组其实有一个构造函数的。他就是Array,所以,上面这句代码,其实是这么一回事:
var arr=new Array();
Array是js自带的一个函数,它是一个构造函数,相当于Java中类的概念。我们可以通过new一个函数的方式,来获得一个实实在在的对象。在这个例子中,arr就是一个实实在在的对象了。我再强调一遍,不要把简单的东西弄复杂了,如果你脑袋里只想着复杂,那么就永远看不到简单。只有对象才可以调用属性和方法。在这个例子中,arr固然是一个对象,所以,它可以调用一个叫做push的方法。
push的意思就是动态地给数组扩容一个单位,并且把对应的值放进去,就这么简单。
有了塞东西进去的方法,当然还有把东西拿出来的方法, 没错就是pop。
var arr=new Array(); //新建一个数组,长度为0 arr.push(100); //动态扩容,现在长度为1 arr.push(200); //动态扩容,现在长度为2 arr.push("我是一个字符串"); arr.pop(); alert(arr);
pop可以理解为弹出,弹出的就是最后一次push进去的值。
3.数组常用方法
接下来,介绍一些数组的常用方法。
3.1 如何复制一个数组
为什么要复制数组呢?因为在实际项目中,你可能会遇到这样的问题。我拿到一个数组,需要临时保存下来,怎么办?你可能会写这样的代码:
var arr=new Array(); //新建一个数组,长度为0 arr.push(100); //动态扩容,现在长度为1 arr.push(200); //动态扩容,现在长度为2 var arr2=arr; arr.pop(); arr.pop(); alert(arr2);
你希望通过arr2来把arr的数据保存下来,结果,一旦arr改变了,arr2也跟着改变了。
不好意思,没有。这是因为arr2和arr都是指向了同一块内存区间,一个改变,另一个也就跟着改变了。那怎么办呢?用slice就可以啦。
var arr=new Array(); //新建一个数组,长度为0 arr.push(100); //动态扩容,现在长度为1 arr.push(200); //动态扩容,现在长度为2 var arr2=arr.slice(); arr.pop(); arr.pop(); alert(arr2);
这样就可以了。
3.2 如何把数组转换成字符串
这个需求也经常会碰到,最常见的就是页面需要做一个批量操作,列表上勾选N条数据,一般来说,是拿到一个JSON数组。比如这样的:
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}];
现在,我要拿到这些id,通过ajax传递到后台,然后后台通过这些id去做某些操作。那换做是你,你打算怎么做呢?有一种办法,就是手动拼接这些id,用逗号分隔一下,做成一个字符串,然后传递到后台,后台再用splite方法进行解析。
你可能会这么做:
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}]; var ids=''; //拼接id for(var i=0;i<rows.length;i++){ if(i==rows.length - 1){ ids +=rows[i].id }else{ ids +=rows[i].id + ','; } } alert(ids);
这样做自然是可以的咯,可是,如果用数组的话,我们可以使用join方法。
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}]; var ids=[]; //拼接id for(var i=0;i<rows.length;i++){ ids.push(rows[i].id); } ids=ids.join(','); //转换成用逗号分隔的字符串 alert(ids);
3.3 如何去除数组中的重复元素
我这边封装了一个简单的方法,可以去重:
var arr=[1,2,3,4,5,1]; function unique(arr){ //新建一个数组,用来存放原数组中所有不重复的数据 var afterUnique=[]; //新建一个JSON对象 var obj={}; //定义一个常量 var EXIST=1; //循环这个数组 for(var i=0;i<arr.length;i++){ /* obj[arr[i]]的意思是在obj中,key为arr[i]的值 如果不等于EXIST,表示不存在,那么就把该数据push到数组中 同时,将这个数据标记为已存在==> obj[item]=EXIST; */ if(obj[arr[i]] !=EXIST){ afterUnique.push(arr[i]); obj[arr[i]]=EXIST; } } return afterUnique; } alert(unique(arr));
当然,这个方法里面也用到了JSON。下一节,我们就来学习一下JSON吧。在本节中,有些地方我故意没有细讲,但凡是我觉得可以通过自行百度来解决的问题,就没有必要在博客中写明了,我也推荐大家能够有目的地去百度一些资料,自己学习。我的博客只讲一些关键的点,以及很多我认为重要的东西,绝对不会像翻字典一样面面俱到,因为我觉得那样没意义,时间一长,还不是忘掉了。只有当你自己真的在项目中遇到了,才会真正的记住。我不希望把读者思维局限在我的文章里面,所以我只讲关键的,常用的。其他东西,留给大家自己去百度,自己去提升。把思路放开来,你会收获更多。
组是用于储存多个相同类型数据的集合,平时在数据的处理中用到最多,JavaScript 中常用的操作方法
1、concat()
concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,仅会返回被连接数组的一个副本。
var arr1=[1,2,3];
var arr2=[4,5];
var arr3=arr1.concat(arr2);
console.log(arr1); //[1, 2, 3]
console.log(arr3); //[1, 2, 3, 4, 5]
2、join()
join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的,默认使用','号分割,不改变原数组。
var arr=[2,3,4];
console.log(arr.join()); //2,3,4
console.log(arr.join('.')); //[2.3.4]
3、push()
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。末尾添加,返回的是长度,会改变原数组。
var a1=[2,3,4];
var a2=a1.push(5);
console.log(a1); //[2,3,4,5]
console.log(a2); //4
4、pop()
pop() 方法用于删除并返回数组的最后一个元素。返回最后一个元素,会改变原数组。
var arr=[2,3,4];
console.log(arr.pop()); //4
console.log(arr); //[2,3]
5、shift()
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。返回第一个元素,改变原数组。
var arr=[2,3,4];
console.log(arr.shift()); //2
console.log(arr); //[3,4]
6、unshift()
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。返回新长度,改变原数组。
var arr=[2,3,4,5];
console.log(arr.unshift(10,100)); //6
console.log(arr); // [10, 100, 2, 3, 4, 5]
7、slice()
返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。返回选定的元素,该方法不会修改原数组。
var arr=[2,3,4,5];
console.log(arr.slice(1,3)); //[3,4]
console.log(arr); //[2,3,4,5]
8、splice()
splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。splice() 方法会直接对数组进行修改。
语法:array.splice(index,howmany,item1,.....,itemX)
Index必需。规定从何处添加/删除元素
howmany必需。规定应该删除多少元素
item1可选。要添加到数组的新元素
var a=[5,6,7,8];
console.log(a.splice(1,0,9)); //[]
console.log(a); // [5, 9, 6, 7, 8]
var b=[5,6,7,8];
console.log(b.splice(1,2,3)); //[6, 7]
console.log(b); //[5, 3, 8]
9、substring() 和 substr()
相同点:如果只是写一个参数,两者的作用都一样:都是是截取字符串从当前下标以后直到字符串最后的字符串片段。
substr(startIndex);
substring(startIndex);
var str='123456789';
console.log(str.substr(2)); // "3456789"
console.log(str.substring(2)) ;// "3456789"
不同点:第二个参数
substr(startIndex,lenth): 第二个参数是截取字符串的长度(从起始点截取某个长度的字符串);
substring(startIndex, endIndex): 第二个参数是截取字符串最终的下标 (截取2个位置之间的字符串,‘含头不含尾’)。
console.log("123456789".substr(2,5)); // "34567"
console.log("123456789".substring(2,5)) ;// "345"
10、sort 排序
按照 Unicode code 位置排序,默认升序
var a=['red', 'blue', 'green'];
a.sort(); // ["blue", "green", "red"]
var num=[1, 10, 21, 2];
num.sort(); // [1, 10, 2, 21]
11、reverse()
reverse() 方法用于颠倒数组中元素的顺序。返回的是颠倒后的数组,会改变原数组。
var arr=[2,3,4];
console.log(arr.reverse()); //[4, 3, 2]
console.log(arr); //[4, 3, 2]
12、indexOf 和 lastIndexOf
都接受两个参数:查找的值、查找起始位置
不存在,返回 -1 ;存在,返回位置。indexOf 是从前往后查找, lastIndexOf 是从后往前查找。
indexOf
var a=[2, 9, 9];
a.indexOf(2); // 0
a.indexOf(7); // -1
if (a.indexOf(7)===-1) {}
lastIndexOf
var numbers=[2, 5, 9, 2];
numbers.lastIndexOf(2); // 3
numbers.lastIndexOf(7); // -1
numbers.lastIndexOf(2, 3); // 3
numbers.lastIndexOf(2, 2); // 0
numbers.lastIndexOf(2, -2); // 0
numbers.lastIndexOf(2, -1); // 3
13、every
对数组的每一项都运行给定的函数,每一项都返回 ture,则返回 true
function fun(element) {
return element < 10;
}
[2, 5, 8, 3, 4].every(fun); // true
function fun(element) {
return element < 10;
}
[2, 5, 11, 3, 4].every(fun); // false
14、filter
对数组的每一项都运行给定的函数,返回 结果为 ture 的项组成的数组
var arr=[1,2,3,4,5];
var a=arr.filter(function(item){
return item !=3;
});
console.log(a) //[1,2,4,5]
15、forEach 数组遍历
var arr=[1, 2, 3];
var arr2=[];
arr.forEach(function(item){
arr2.push(item+1)
});
console.log(arr2) // [2, 3, 4]
感谢大家的支持,小编给粉丝们准备了书籍+视频资料哦。麻烦转发+关注。私信我“资料".
击右上方红色按钮关注“小郑搞码事”,每天都能学到知识,搞懂一个问题!
如何实现深拷贝?
就是递归调用浅拷贝方法。
基本类型值的拷贝属于深拷贝,然而,值的分析的是数组和对象的深拷贝实现问题。两者的分析思路完全类同,包含代码实现和方法利用。所以,今天先来总结一下数组的深拷贝问题。主要看看有哪些是你我想到一块去的地方。
通过逐个拷贝数组中的元素来实现一维数组的深拷贝。
来看一段代码:
上面这段代码,从执行结果来看,实现了一个一维数组的深拷贝,拷贝后的数组和源数组完全是独立的。
以二维为例子,比一维稍微复杂点,实现思路就是递归一维的代码,来保证每次拷贝的都是基本类型值。
数组中的slice和concat方法,对于数组元素为基本数据类型的情况,可以实现数组的深拷贝。相信大家都会用。
*请认真填写需求信息,我们会在24小时内与您取得联系。