一、数组的基础
1.1 创建数组
- 直接量方式:
var arr = [值1,值2...]
- 构造函数:
var arr = new Array(值1,值2...)
var arr = new Array(3)//表示创建了一个长度为3的空数组
二、按值传递
var a = x; var b = a;修改a/b,看b/a变不变。
- 传递的如果是原始类型: 其实是复制了一个副本给对方,两者互不影响
- 传递的如果是引用类型(浅拷贝): 因为引用类型很大,比原始类型大得多,不可能保存在变量本地,只是保存了一个地址值而已,其实是复制了自己的地址值给对方,两者用的是同一个地址值,一个修改另一个也会变化。
// 第一种 原始数据类型 不会跟着变化
var a = 1
var b = a
console.log(a,b);//1 1
a = 3
console.log(a,b);//3 1
// 第二种 引用数据类型 会跟着变化
var a = [1,2,3]
var b = a
console.log(a,b);//[1,2,3] [1,2,3]
a.length--
console.log(a,b);//[1,2] [1,2]
三、如何释放一个引用类型
每个变量都释放后才能释放干净
在js底层有一个垃圾回收器,只有垃圾回收器的计数器(记录着这个数据有几个人引用着)为0的时候才会删除不要的数据
建议:我们的代码要封装为一个函数,函数中的一切变量都会自动释放
四、hash数组
索引数组:下标都是数字组成的数组
hash数组(关联数组):下标是可以自定义的
为什么:索引数组的下标无具体意义,不便于查找
4.1 创建:
- 创建新数组:var arr=[];
- 为数组添加自定义下标并且赋值:arr["自定义下标"]=新值;
4.2 访问元素:
arr["自定义下标"];
4.3 hash数组的length失效了,永远为0!
4.4 遍历hash数组:
不能再使用for循环,必须使用for in循环
for(var i in 数组名){
i;//下标
数组名[i];//当前次元素
}
// 创建hash数组
var arr = []
arr["name"] = "张三"
arr["age"] = 18
console.log(arr)
// 访问hash数组
console.log(arr["name"]);
遍历hash数组
for(var i in arr) {
console.log(i);//name age
console.log(arr[i]);//张三 18
}
4.5 hash数组的原理:
hash算法:将字符串,计算出一个尽量不重复的数字(地址值),字符串内容相同,则计算出来的数字也一定是相同的
添加元素:将自定义下标交给hash算法,得到一个数字(地址值),直接将你要保存的数据放到此地址保存起来
获取元素:将指定的自定义下标交给hash算法,得到一个和当初保存时一样的数字(地址值),通过此地址找到你当初保存的数据,取出来使用
- js里面一切的东西都是对象,万物皆对象,除了undefined和null,【一切对象的底层都是hash数组】
五、数组的API
前辈们预定义了很多方法,等待我们学习,我们程序员只需要学会如何使用,就可以直接用上 - 这些方法只有数组可用
5.1 arr 转 str:
var str=arr.join("自定义连接符");//不修改原数组
固定套路(2个):
- 将数组里面的内容拼接为一句话/单词 - 无缝拼接
var arr=["h","e","l","l","o"," ","w","o","r","l","d"];
var str=arr.join("");
console.log(str);
- 将数组拼接为DOM页面元素
//拿数据
var arr=["-请选择-","北京","南京","西京","东京","重庆","北京","南京","西京","东京","重庆","北京","南京","西京","东京","重庆","北京","南京","西京","东京","重庆","北京","南京","西京","东京","重庆","北京","南京","西京","东京","重庆"];
//将数组拼接为页面标签字符串
var str="<开始标签>"+arr.join("</结束标签><开始标签>")+"</结束标签>";
//innerHTML能够识别标签
sel.innerHTML=str;
5.2 数组拼接:
添加元素的新方式,将你传入的实参全部拼接到arr的末尾
var newArr=arr.concat(新值1,arr1,...);//不修改原数组
var arr1 = [1,2,3,4,5]
var arr2 = [6,7,8,9,10]
var newArr = arr1.concat(arr2)
console.log(newArr);//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr1);//[1,2,3,4,5]
console.log(arr2);//[6,7,8,9,10]
- 不修改原数组,只会返回一个新数组
- concat支持传入数组参数,悄悄的将你传入的数组打散为单个元素再拼接
5.3 截取子数组:
根据你传入的开始下标截取到结束下标
var subArr=arr.slice(starti,endi);//不修改原数组
- 不修改原数组,只会返回一个新数组
- 含头不含尾
- endi可以省略不写,如果省略,会从starti位置一直截取到末尾
- starti也可以省略,如果两个实参都省略,那么会从头到尾完全的复制一份:此操作也叫做深拷贝 - 复制了一个副本给对方
- 支持负数参数,-1代表倒数第1个
// 从下标为0的位置开始截取到下标为2结束 含头不含尾
var newArr = arr.slice(0,2)
console.log(newArr);//返回的是被截取的新数组 [1, 2]
console.log(arr);//[1, 2, 3, 4, 5]
5.4 删插替:
- 删除:
var dels=arr.splice(starti,n);//n代表删除的个数
var arr = [1,2,3,4,5]
var newArr = arr.splice(0,2)
console.log(arr);//[3, 4, 5]
console.log(newArr);//[1, 2]
- 虽然他直接修改原数组,但是也有返回值,返回的是被删除的数据组成的一个新数组,因为前辈们考虑到有可能删除的东西刚好是需要的东西,哪怕没有删除也会返回一个空数组
- 插入:
arr.splice(starti,0,新值,...);
var arr = [1,2,3,4,5]
var newArr = arr.splice(1,0,"1")
console.log(arr);//[1, '1', 2, 3, 4, 5]
console.log(newArr);//[]
- 原starti位置的元素以及后续元素都会向后移动
- 尽量的不要插入一个数组,会导致我们的数组一些是一维,一些是二维,遍历的时候就非常不方便
- 替换:
var dels=arr.splice(starti,n,新值,...);
var arr = [1,2,3,4,5]
var newArr = arr.splice(2,2,"1","22","6")
console.log(arr);//[1, 2, '1', '22', '6', 5]
console.log(newArr);//[3,4]
- 删除的个数和插入的个数不必相同
5.5 翻转数组:
arr.reverse();
var arr = [1,2,3,4,5]
arr.reverse()
console.log(arr);//[5, 4, 3, 2, 1]
5.6 数组排序:
- 冒泡排序:
// 冒泡排序
var arr = [22,15,2,6,99,8,44,56,45,1,2,66,2,5]
for(var j = 0; j < arr.length - 1; j++) {
for(var i = 0; i < arr.length - j; i++) {
if(arr[i+1] < arr[i]) {
var n = arr[i]
arr[i] = arr[i+1]
arr[i+1] = n
}
}
}
console.log(arr);//[1, 2, 2, 2, 5, 6, 8, 15, 22, 44, 45, 56, 66, 99]
- arr.sort():
默认:将数组中的元素转为字符串后,再按位PK每个字符的unicode号(ASCII码)
- 希望按照数字升序排列:
var arr = [22,15,2,6,99,8,44,56,45,1,2,66,2,5]
arr.sort(function(a,b){
return a - b
})
console.log(arr);//[1, 2, 2, 2, 5, 6, 8, 15, 22, 44, 45, 56, 66, 99]
- 希望按照数字降序排列:
var arr = [22,15,2,6,99,8,44,56,45,1,2,66,2,5]
arr.sort(function(a,b){
return b - a
})
console.log(arr);//[99, 66, 56, 45, 44, 22, 15, 8, 6, 5, 2, 2, 2, 1]
以后只要网页上有功能带有排序,他的底层一定是数组,因为js中只有数组可以排序
以后只要网页上有随机的功能,那么他的底层一定用到了随机数公式!
六、select专属
- select专属事件onchange - 只有在选中项发生变化后才会触发
- select专属属性selectedIndex - 获取到当前选中项的下标
七、案例
<body>
<select name="" id=""></select>
<select name="" id=""></select>
<script>
// 二级联动
var city1 = ['-请选择-','北京','湖北','陕西','重庆','内蒙古']
var city2 = [
['-请选择-'],
['朝阳','东城','海淀'],
['武汉','咸丰','荆州'],
['西安','汉中'],
['渝中','九龙坡'],
['巴彦卓尔','乌兰察布']
]
var sels = document.getElementsByTagName('select')
sels[0].innerHTML = '<option>' + city1.join('</option><option>') + '</option>'
sels[0].onchange = function(){
var i = sels[0].selectedIndex//拿到下标
sels[1].innerHTML = '<option>' + city2[i].join('</option><option>') + '</option>'
}
sels[0].onchange()
</script>
</body>