2016-08-26-day06-am
1.数组
- 什么是:内存中,连续存储多个数据的存储空间,再起一个名字
一组变量的集合 - 为什么:现实中存储多个相关数据,都是集中存储,共用同一个名字。
程序=数据结构+算法
好的数据结构可以极大的提高程序的执行效率 - 何时:今后只要连续存储多个相关的数据都要用数组
- 如何使用: 创建数组的3种方法如下:
1.创建空数组: 2种:
数组直接量: var arr=[];
用new: var arr=new Array();
2.创建数组同时,初始化数组的数据:
数组直接量: var arr=[值1,值2,...]
用new: var arr=new Array(值1,值2,...);
3. 创建n个空元素的空数组:
1.只能用new: var arr=new Array(n);
- 访问数组中的元素:
下标: 数组中唯一标识一个元素存储位置的序号
默认从0开始,连续递增,不重复
arr[i]: 访问下标为i位置的元素
数组中,每个元素的用法和普通变量完全一样。 - 数组的length属性:
标识了数组中理论上的元素个数
任何情况下: length永远是最大下标+1
固定套路:
最后一个元素: arr[arr.length-1]
倒数第n个元素: arr[arr.length-n]
追加新元素:arr[arr.length]=新值;
缩容: arr.length--;
以下是一个简单的数组例子
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
var arr=["一","二","三","四","五"];
// 0 1 2 3 4
console.dir(arr);
console.log(arr[2]);//获取下标2位置的元素值
//取出下标2位置的值,拼上"星期",再放回2位置
arr[2]="星期"+arr[2];
//获取元素时越界,不报错,返回undefined
console.log(arr[10]);
//设置元素时越界,自动添加新元素
arr[6]="星期日";
//固定套路:
console.log(
arr[arr.length-1],//倒数第一个元素
arr[arr.length-3]//倒数第三个元素
);
arr[arr.length]="星期八";//末尾追加新元素
</script>
</body>
</html>
- 特殊情况: js中的数组:3个不限制
1.不限制元素的数据类型
2.不限制下标越界
获取元素值:
下标越界: 不报错,返回undefined
3.不限制元素的个数
设置元素值:
下标越界:
自动在指定位置添加新元素
自动修改length为最大下标+1
稀疏数组: 下标不连续的数组 - 遍历数组: 依次访问数组中每个元素
for(var i=0;i<arr.length;i++){
arr[i]//当前元素
}
以下几个与数组有关的小练习
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
/*
var emps=[];//创建空数组emps
//声明ename为空字符串
var ename="";
//反复执行: //请用户输入员工姓名,保存在ename中,如果ename不是exit
while((ename=prompt("输入姓名"))!="exit"){
//将ename追加到数组emps末尾
emps[emps.length]=ename;
}
//输出:
console.dir(emps);
*/
/*
//找出数组中一个最大值:
var arr=[1,2,3,4,3,2,1];
// max=4
function getMax(arr){
//遍历arr中每个元素,同时声明变量max,赋值为数组第1个元素
//如果当前元素>max,就将max赋值为当前元素
for(var i=0,max=arr[0];
i<arr.length;
arr[i]>max&&(max=arr[i]),i++);
return max;//返回max
}
console.log(getMax(arr));//4
*/
var arr=[1,2,3,2,1];
// 0 1 2 3 4
//定义indexOf函数
//可以从指定位置开始,查找下一个指定值得下标位置
//如果找不到,返回-1
function indexOf(arr,val,fromi){
//如果fromi是undefined就赋值为0
fromi===undefined&&(fromi=0);
//从fromi开始,遍历arr中剩余元素
for(;fromi<arr.length;fromi++){
//如果当前元素等于val
if(arr[fromi]==val){
return fromi;//返回fromi
}
}//(遍历结束)
return -1; //返回-1
}
//在arr中从0位置开始找下一个元素值为2的位置
console.log(indexOf(arr,2));//1
//在arr中从2位置开始找下一个元素值为2的位置
console.log(indexOf(arr,2,2));//3
//在arr中从4位置开始找下一个元素值为2的位置
console.log(indexOf(arr,2,4));//-1
//在arr中从0位置开始找下一个元素值为4的位置
console.log(indexOf(arr,4));//-1
</script>
</body>
</html>
- 数组是引用类型的对象:
引用类型的例子
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
//按值传递:两个变量间赋值时,或将变量作为参数传入函数时,其实仅将原变量中的值复制一个副本给对方
//原始类型的值: 修改新变量,不影响原变量
var a=3;
var b=a;//a将自己的值复制了一个副本给b
a++;
console.log(b);//3
console.log(a);//4
var card=10;
function buy(card){
card-=3;
console.log("余额"+card);
}
buy(card);//7
console.log(card);//10
//引用类型的对象: 用原变量修改对象,新变量同样受影响。因为两个变量引用的是同一个对象
var dd=["包","包","包","包","包"];
/*
var xx=dd;
dd.length--;
console.log(String(xx));//4个
console.log(String(dd));//4个
xx.length--;
console.log(String(xx));//3个
console.log(String(dd));//3个
*/
function eat(arr){
arr.length--;
console.log(arr.length);
}
eat(dd);//4
console.log(dd.length);//4
</script>
</body>
</html>
pm
1.垃圾回收: 定期回收不再被任何变量引用的对象。释放内存。
- 垃圾回收器:
伴随主程序,并行运行的一个小程序
定期回收内存中的不再被任何变量引用的对象。 - 引用计数器:
每个对象上,标记正在引用对象的变量个数的一个属性
每多一个变量引用对象,计数器就+1
如果一个变量通过赋值为null释放对对象的引用,则计数器-1
直到计数器为0,表示不再有任何变量引用该对象,则该对象被回收/释放
建议: 如果使用完较大的对象,都要主动赋值为null。
2.关联数组:
- 什么是:可自定义下标名称的数组
- 为什么:普通的索引数组的下标都是无意义的数字。不便于快速查找元素。也容易出现歧义.
[林心如, 81, 53, 86]
name math chs eng - 何时:希望每个元素有专门的名称时
通常用于快速定位元素 - 如何使用: 创建: 2步:
1.创建空数组: var lxr=[];
2.向空数组中添加新元素:
使用自定义的字符串元素名作为下标
lxr["name"]="林心如";
lxr["math"]=81;
lxr["chs"]=53;
lxr["eng"]=86;
- 访问元素: lxr["name"]
- 强调: 关联数组的length失效
- 遍历: 不能用for循环
用for in循环: 其中in,表示依次取出数组中每个下标
for(var key in hash){
key//每个元素的下标名称
hash[key]//当前元素值
}
- 关联/hash数组原理:
hash算法: 接收一个字符串,并计算出一个尽量不重复的序号
相同的字符串,计算出的号总是一样的
不同的字符串,计算出的号大多数不重复
存入数据:
hash算法接收一个字符串的下标名,计算出一个不重复的序号。将数据存储在序号对应的数组位置上
获取数据:
将下标名称交给hash算法,算出和存入时完全相同的序号,直接去序号位置查找元素
优点: 查找极快!
和数组中元素个数,以及元素在数组中的位置无关。
以下是hash的简单例子:
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
/*
var lxr=[];
lxr["name"]="林心如";
lxr["math"]=81;
lxr["chs"]=53;
lxr["eng"]=86;
console.dir(lxr);
console.log(lxr["math"]);
//遍历:
for(var key in lxr){
//name : 林心如
console.log(key+":"+lxr[key]);
}
*/
var arr=["a","b","a","c","a","b"];
function unique1(arr){
//遍历arr中每个元素,同时声明空数组uarr
for(var i=0,uarr=[];i<arr.length;i++){
//遍历uarr中每个元素
for(var j=0;j<uarr.length;j++){
//如果uarr中当前元素等于arr中当前元素
if(uarr[j]==arr[i]){
break;//就退出循环
}
}//(遍历结束)
//如果j等于uarr的length
//将arr中当前元素加入uarr中
j==uarr.length&&(uarr[j]=arr[i]);
}//(遍历结束)
return uarr;//返回uarr
}
function unique2(arr){
//遍历arr中每个元素,同时创建空数组hash
for(var i=0,hash=[];i<arr.length;i++){
//如果hash中以arr中当前元素值为key的元素等于undefined
if(hash[arr[i]]===undefined){
//就在hash中添加一个新元素,key为arr中当前元素,值为1
hash[arr[i]]=1;
}
}//(遍历结束)hash:["a":1,"b":1,"c":1]
i=0;//设置i=0
var keys=[]//定义空数组keys
for(keys[i++] in hash);
return keys;
}
var uarr=unique1(arr);
console.log(String(uarr));//a,b,c
/*
//随机生成十万个0~999之间的数,放入数组arr
for(var i=0,arr=[];i<100000;i++){
arr[arr.length]=
parseInt(Math.random()*1000);
}
//设置测试开始时间
console.time("unique1");
unique1(arr);//调用被测函数
//设置测试结束时间,并打印时间差
console.timeEnd("unique1");//ns
console.time("unique2");
unique2(arr);
console.timeEnd("unique2");//ns
*/
</script>
</body>
</html>
数组API:
对象: 集中存储多个数据的一块存储空间, 并提供了操作数据的API
函数: 不属于任何对象的函数
方法: 必须用对象才能调动的函数,叫方法
-
1. 转字符串: 2种
- 将数组中每个元素都转为字符串,再用逗号分隔: var str=String(arr);
- 将数组中每个元素都转为字符串,再用自定义下标连接每个元素:
var str=arr.join("自定义连接符")
强调:如果省略参数,默认等效于String
固定套路:
1. 无缝拼接: arr.join("")
2. 将单词拼接为句子: arr.join(" ")
3. 判断空数组: arr.join("")==""
4. 根据数组中的元素,动态生成页面元素的内容
例子:
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<select id="sel">
</select>
<script>
//无缝拼接
var chars=["H","e","l","l","o"];
console.log(chars.join(""));
//单词拼接为句子
var words=["no","zuo","no","die"];
console.log(words.join(" "));
//判断空数组
var arr=[,,,,,,,,,];
console.log(arr.join(""));
//动态生成页面元素的内容
var provs=["北京市","天津市","山东省","河南省","山西省"];
var html="<option>"+
provs.join("</option><option>")
+"</option>";
//设置id为sel的元素开始标签到结束标签之间的html内容
sel.innerHTML=html;
</script>
</body>
</html>
-
2. 拼接和截取:
拼接:
var newArr= arr1.concat(值1,值2,arr2,....)
将值1,值2,以及arr2中每个元素依次拼接到arr1结尾,返回新数组。
何时使用: 将多个元素或其他数组,拼接到当前数组上时
强调:
1.concat无权修改原数组,只能返回新数组
所以,必须用变量接住拼接后的返回值
2.concat可打散数组类型的参数为单个元素**
截取:(复制)
var subArr=arr.slice(starti,endi+1);
复制arr中starti位置开始到endi结束的元素组成子数组返回。
何时: 选取数组中指定位置的子数组时
强调:
1. 无权修改原数组,只返回新子数组
2.含头不含尾
3.其实可使用负数参数,表示倒数第n个
简写:
1. 省略第二个参数,表示一直截取到结尾
2. 两个都省略,表示完整复制原数组中的元素到新数组。
不能只省略第一个参数——报错
例子:
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
var arr1=[1,2,3];
//拼接
var newArr=arr1.concat(12,23,[123,234]);
console.dir(arr1);//原数组不变
console.dir(newArr);//只返回新数组
//[1,2,3,12,23,123,234]
// 0 1 2 3 4 5 6
// 3 2 1-
//选取3到4位置的两个元素
var subArr=//newArr.slice(3,4+1);
//newArr.slice(3);//选到结尾
//完整复制: 新数组和原数组不是同一个数组对象,地址不同
//newArr.slice();
//第一个参数不能省
//newArr.slice(0,3);
//可使用负数下标,表示倒数
//newArr.slice(-3,-2+1);
//其实是:
newArr.slice(newArr.length-3,
newArr.length-2+1)
//var subArr=newArr;
//两个对象做==比较,不比内容,而比地址!
//console.log(subArr==newArr);//false
console.log(String(newArr));
console.log(String(subArr));
</script>
</body>
</html>
-
3.splice: 删除,插入,替换
删除数组中指定位置的元素:
arr.splice(starti,n):
删除arr中starti位置开始的n个元素
其实: var deletes=arr.splice(starti,n)
deletes: 返回的被删除的元素组成的临时子数组。在数组指定位置插入新元素:
arr.splice(starti,0,值1,值2,...)
在starti位置插入新值
原starti位置的值被向后顺移强调: splice,不支持打散数组参数
插入: splice vs concat
concat只能在开头或结尾拼接,不能中间插入。但可打散数组类型参数
splice可在任意位置插入,但不可打散数组类型参数。
替换数组中指定位置的元素
arr.splice(starti,n,值1,值2,...)
先删除starti位置的n个旧元素
再在starti位置插入新值
强调: 删除的个数和插入的个数不必一致
splice可自动调节数组的长度和位置
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<script>
var arr=[1,2,3,4,5];
// 0 1 2 3 4
/*
//删除开头的2个元素,再拼接到arr结尾
arr=arr.concat(arr.splice(0,2));
console.log(String(arr));//[3,4,5,1,2]
//删除结尾的2个元素,再拼接到arr开头
arr=arr.splice(arr.length-2,2).concat(arr)
console.log(String(arr));
*/
//arr.splice(2,0,12,23,[123,234]);
//console.dir(arr);
arr.splice(1,2,12,23,123);
console.log(String(arr));
//1,12,23,123,4,5
</script>
</body>
</html>
翻转: arr.reverse();