Day5:数组的定义、遍历
一、数组
1、程序=数据结构(数据在程序中的存储结构)+算法 良好的数据结构可以极大的提高程序的执行效率
2、定义
存储:连续存储多个数据的存储空间
使用:相当于多个变量的集合
3、为什么要使用数组
因为现实中数组都是批量分类管理
何时使用:只要批量管理多个数据,就要用数组保存
如何使用:
(1)创建:数组都是用中括号([])创建出来的
var arr=[]; //创建一个数组对象,数组中包含0个元素
var arr=[34,45,33]; //创建了一个数组对象,数组中连续存储3个元素,34、45、33
数组的其他创建方式:(知道就行,一般不要用)
为什么不要用这种方式创建?
假设我让你创建一个数组,里面有一个元素,数字7
var arr=new Array(7) //这种是在堆中开辟7个存储空间
var arr=new Array('7') //创建一个字符串7
由此可得,这种方式容易让人产生歧义
var arr=new Array(num);
new:只要看到new,就是要在堆中开辟空间(var 栈中)
Array:ECMAScript标准中的内置类型
new Array:在堆中创建一个数组类型的存储区域
(num):初始创建num个元素
例如: var arr=new Array(7) //[undefined,undefined,undefined,undefined,undefined,undefined,undefined] 但是undefined在输出时会变为一个空字符
var arr=new Array(元素1,元素2,...元素n);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var week=['日','一','二','三','四','五','六'];//中间用逗号分隔,最后一个不加逗号
//栈中创建一个变量,名为week
//堆中创建一个大存储空间:地址可能是019x8
//栈中变量中存储的是地址019x8
//堆空间中存储的是实际数据
//week变量引用了堆中的一个数组对象
document.write(week+'<br/>');
var arr=new Array(7);
document.write(arr+'<br/>');
var week1=new Array('日','一','二','三','四','五','六');
document.write(week1+'<br/>');
</script>
</body>
</html>
注:数组有两个不限制 1、不限制元素个数 2、不限制元素数据类型
数组是引用类型的对象: 1、原始类型:数据保存在变量本地 2、引用类型:数据不保存在变量本地,保存在‘堆’中,由地址指向实际数据,它的最大特点是:可以保存多个数据,而且数据个数随时可变 3、为什么要使用原始类型? 原始类型中只能保存1个值 一个值无法精确描述一个东西 现实中,都是用多个属性共同描述一样东西

对象:凡是存储在堆中的都是对象
使用引用类型的对象:使用变量,等效于使用对象的地址,使用对象地址等效于使用对象本身
数组对象支持直接输出对象内容
(2)null:一个变量,没有指向任何对象
何时使用null:主动释放对象,主动释放的对象不能被找回了
null vs undefined:
null:专用于主动释放对象
undefined:专用于自动初始化任何未赋值的变量
垃圾回收:js引擎自动销毁不再被引用的对象
垃圾回收程序:随js程序运行而后台同时运行,有延迟,只要对象还有变量引用,就不回收
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <script> var week=['日','一','二','三','四','五','六'];//中间用逗号分隔,最后一个不加逗号 //栈中创建一个变量,名为week //堆中创建一个大存储空间:地址可能是019x8 //栈中变量中存储的是地址019x8 //堆空间中存储的是实际数据 //week变量引用了堆中的一个数组对象 document.write(week+'<br/>'); var day=week;//值传递:将内部数值赋值给新变量 week=['SUN','MON','TUS'];//新创建一个数组对象 //将新对象地址保存到原week变量中替换旧地址 //旧数组对象释放,等待垃圾回收 //week变量引用了新数组对象 </script> </body> </html>
4、访问数组:一组变量的集合
(1)如何获取其中一个变量/数据:下标
(2)下标:数组中唯一标识一个元素的序号,从0开始,数组最后一个元素的下标是 元素个数-1
如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var week=['日','一','二','三','四','五','六'];//中间用逗号分隔,最后一个不加逗号
//栈中创建一个变量,名为week
//堆中创建一个大存储空间:地址可能是019x8
//栈中变量中存储的是地址019x8
//堆空间中存储的是实际数据
//week变量引用了堆中的一个数组对象
document.write(week+'<br/>');
var day=week;//值传递:将内部数值赋值给新变量
week=['SUN','MON','TUS'];//新创建一个数组对象
//将新对象地址保存到原week变量中替换旧地址
//旧数组对象释放,等待垃圾回收
//week变量引用了新数组对象
console.log(week[2]);//取出下标为2位置的变量
console.log(week[4]);//越界读取元素返回undefined,不会出错
</script>
</body>
</html>
(3)js内置对象不但封装存储,而且封装常用API
API:已经实现的方法,可以直接调用
(4)Array API
arr.length:属性(不能执行操作,但是能返回一个数,不加圆括号),数组的长度(元素的个数)
访问任意数组的最后一个元素:arr[arr.length-1]
length属性值,随数组长度变化而自动变化
js中数组可以根据程序的需要,自动扩容,保证程序正常执行,保证程序正常运行
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var week=['日','一','二','三','四','五','六'];
week=[];
console.log(week.length);//0
week[0]='日'
console.log(week.length);//1
week[2]='二'
console.log(week.length);//3['日',undefined,'二']
week[4]='四'
console.log(week.length);//5['日',undefined,'二',undefined,'四']
document.write(week);//日,,二,,四
</script>
</body>
</html>
(5)数组的扩容和缩容:
如果length属性值>旧值 ,会扩容,反之缩容(截断),被截断的元素不能被找到,不会被回收,只能随数组对象一起回收
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var week=['日','一','二','三','四','五','六'];
week=[];
console.log(week.length);//0
week[0]='日'
console.log(week.length);//1
week[2]='二'
console.log(week.length);//3['日',undefined,'二']
week[4]='四'
console.log(week.length);//5['日',undefined,'二',undefined,'四']
document.write(week+'<br/>');//日,,二,,四
week.length=7;
console.log(week.length);//7
document.write(week+'<br/>');//日,,二,,四,, 扩容
week.length=3;
console.log(week.length);//3
document.write(week+'<br/>');//日,,二 缩容
</script>
</body>
</html>
(6)在任意数组结尾追加一个新元素(固定用法):
arr[arr.length]=新值;
(7)练习题:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
//不停录入员工姓名,知道输入exit退出,将这些姓名保存在一个数组中,控制台中输出所有元素
var input;
var emps=[];
while(true){
input=prompt('输入姓名');
if(input!='exit'){
emps[emps.length]=input;
}else{
break;
}
}
document.write(emps);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
//不停录入员工姓名,知道输入exit退出,将这些姓名保存在一个数组中,控制台中输出所有元素
var input;
var emps=[];
//赋值同时用表达式的值做判断
while((input=prompt('输入姓名'))!='exit'){
emps[emps.length]=input;
}
document.write(emps);
</script>
</body>
</html>
(8)
栈中的变量生命周期:和堆完全不同
var a=5;
function fun(){
var b=10;
}
fun();//作用域环境栈
fun的作用域环境栈 出栈 fun的中局部变量一同消失
cosole.log(b) //refError
结论:局部变量的生命周期和所在方法的作用域环境栈有关
作用域创建,局部变量一同创建
作用域结束,局部变量一同消失
二、遍历数组元素
定义:对数组中的每个元素执行相同的操作
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var week=['日','一','二','三','四','五','六'];
document.write(week+'<br>');
for(var i=0;i<week.length;i++){
week[i]='星期'+week[i];
}
document.write(week);
</script>
</body>
</html>
1、关联数组:数组下标可以自定义名称 key/value
(1)何时使用关联数组:数组元素内容无法描述自己的意义时,使用关联数组为每个元素起名
(2)for in:专门用来遍历关联数组用的,为什么不能用.length那种方法循环,因为length已经不能使用了
for(var key in arr){
//从第一个元素开始,将元素的key赋值给临时变量key
arr[key]-->当前正在遍历的元素的值(value)
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var fbb=[];
fbb['姓名']='李春雨';
fbb['年龄']=24;
for(var key in fbb){
document.write(key+':'+fbb[key]+'<br>');
}
</script>
</body>
</html>
(3)关联数组直接量定义方式:{‘key1’:'value1','key2':'value2'},必须使用大括号
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var fbb={'姓名':'李春雨','年龄':24};
for(var key in fbb){
document.write(key+':'+fbb[key]+'<br>');
}
</script>
</body>
</html>
二、冒泡排序(还有一个是选择排序)
定义:冒泡排序法的具体实现方法是这样的,从数组的第一个元素`arr[0]`开始,两两比较(`arr[n],arr[n+1]`),如果前面的数大于后面的数(`arr[n] > arr[n+1]`),那么交换两个元素的位置,把大的数往后移动。这样依次经过一轮比较以后,最大的数将会被交换到最后的位置(arr[n-1])
1、算法:[3,5,2,6,7,9,8,4]升序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
//循环条件:当前元素下标<length-1
//循环变量:下标,从0开始
//循环体:当前元素>下一个元素 交换
var arr=[5,3,2,6,4,9,8,7];
//将最大数置换到最后一个元素
//从第一个数开始,依次取出每个元素和下一个数作比较
for(var n=1;n<=arr.length-1;n++){
for(var i=0;i<arr.length-n;i++){
var curr=arr[i];
var next=arr[i+1];
if(curr>next){//交换
var box=arr[i];//将i数据取出
arr[i]=arr[i+1];//将i+1的数据放入i
arr[i+1]=box;//将取出的数据放入i+1
}
}
}
console.log(arr);
</script>
</body>
</html>
二、数组的常用方法
(1)x.toString()方法:任何对象都有toString方法,默认用逗号分隔每个元素,将任何对象转换成字符串,一般不主动调用,js在需要时自动调用
(2)x.valueOf()方法:同toString
(3)var str=arr.join('分隔符'):将数组转为字符串,可自定义分隔符
将字符拼接为单词或者句子
var chars=['h','e','l','l','o'];
console.log(chars.join(''));//hello
(4)var newArr=arr.concat(元素值,[数组]):将参数拆散成单个元素追加到数组中,不会修改原数组,只能返回新数组对象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var chars=[1,2,3];
var chars1=[12,33,323];
var newchar=chars.concat(chars1,99);
document.write(newchar);
</script>
</body>
</html>
(5)var subArr=arr.slice(start,end+1):截取数组下标从start开始,到end位置的元素,生成子数组对象
含头不含尾:如例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var chars=[1,2,3];
var chars1=[12,33,323];
var newchar=chars.concat(chars1,99);
document.write(newchar+'<br>');
//截取下标位置为2开始到4之间的元素
var newchar2=newchar.slice(2,4+1);
document.write(newchar2);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var chars=[1,2,3];
var chars1=[12,33,323];
var newchar=chars.concat(chars1,99);
document.write(newchar+'<br>');
//截取下标位置为倒数2开始到倒数4之间的元素
//var newchar2=newchar.slice(newchar.length-4,newchar.length-2+1);
var newchar2=newchar.slice(-4,-2+1);
document.write(newchar2);
</script>
</body>
</html>
(6)arr.splice:删除、插入、替换
删除数组元素:arr.splice(start,count);
替换数组元素:arr.splice(start,count,值1,值2....);
插入数组元素:arr.splice(start,0,值1,值2....);
返回每次被删除元素组成的新数组
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var chars=[1,2,3];
var chars1=[12,33,323];
var newchar=chars.concat(chars1,99);
document.write(newchar+'<br>');
//newchar.splice(2,2); //删除
//document.write(newchar+'<br>');
//newchar.splice(2,2,77,88,99); //替换
//document.write(newchar+'<br>');
newchar.splice(2,0,33); //插入
document.write(newchar+'<br>');
</script>
</body>
</html>
(7)arr.reverse():颠倒数组所有元素
(8)arr.sort():默认升序排列,默认都转为字符串排序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var chars=[22,1,2,3];
var chars1=[12,33,3];
var newchar=chars.concat(chars1,99);
document.write(newchar+'<br>');
newchar.sort();
document.write(newchar+'<br>');
</script>
</body>
</html>
浙公网安备 33010602011771号