1.数组的基础:一个变量可以保存多个数据
1、创建:2种
1、直接量:var arr=[值1,....];
2、构造函数:var arr=new Array(值1,....);//缺陷:面试中:new Array(3);设置一个长度为3的空数组
2、访问:
获取:arr[i]; - 特殊:下标越界:得到undefined
添加/替换:arr[i]=新值; - 特殊:下标越界:得到稀疏数组
3、*3大不限制:
不限制长度、类型、下标越界(不是好东西)
4、length的三个固定套路:
获取倒数第n个元素:arr[arr.length-n];
向末尾添加元素:arr[arr.length]=新值
缩容:arr.length-=n;
5、遍历数组:
for(var i=0;i<arr.length;i++){
arr[i];//当前次元素
}
6、特殊点:如何释放一个引用类型:
要看清楚这个引用类型对象有几个变量名引用着,每个变量都要释放才能真的释放干净
7、知识点:
索引数组:下标都是数字组成的数组 - 默认
关联(hash)数组:下标是可以自定义的数组
为什么要自定义下标:索引数组的下标无具体意义,不便于我们查找
创建:2步
1、创建一个空数组:var arr=[];
2、添加自定义下标并且赋值:arr["自定义"]=值
访问:arr["自定义下标"];
遍历:把所有的元素都取出来执行 相同 或者 相似的操作
问题:不能使用for循环,因为length失效了,关联数组永远为0,而且下标也在是一个数字
解决:for in循环:
语法:for(var i in 数组名){
数组名[i]
}
无敌:不光可以遍历关联数组,也可以遍历索引数组
个人建议:索引数组依然使用for循环
关联数组只能使用for in循环
***JS中除了undefined和null不是一个对象,万物皆对象,而且一切对象的【底层都是hash数组】
hash数组的原理:
hash算法:将字符串交给hash算法,会得到一个尽量不重复的数字,但是字符串内容相同的,那么得到的数字一定也是相同的
添加元素:将自定义的下标交给hash算法,得到一个数字(地址值),把要保存的数据放到那个地址之中
获取元素:将指定的下标交给hash算法,得到一个和添加时完全相同的数字(地址值),得到这个地址值之中保存这的数据了
2.数组的API:函数:前辈们预定义的好的,但是只有数组可以使用的方法
1、数组 转为 字符串:
var str=arr.join("自定义连接符");
特殊:
1、如果没有传入实参,则和toString/String,完全一样,默认由,分割
2、固定套路:2个
1、鄙视题:提供一个数组给你,让你无缝拼接数组里面的内容变为一个字符串
var arr=["h","e","l","l","o"," ","w","o","r","l","d"];
var str=arr.join("")
console.log(str);//"hello world";
2、开发中:将数组中的数据拼接为页面上的元素:初级版数据渲染
var cities=["北京","南京","西京","东京","重庆"];
var str="<option>"+cities.join("</option><option>")+"</option>";
sel.innerHTML=str;//innerHTML可以识别标签
实现:二级联动:4个重点
1、必须使用二维数组,而且二维数组的数据顺序一定要和一级的对应上
2、select专属事件:select.onchange:状态改变事件:选中项发生改变才会触发
3、select具有一个属性:this.selectedIndex;获取选中项的下标 - 只有select不需要自定义下标
4、其实绑定事件的部分就是函数名,也可以拿来调用
2.拼接数组:添加元素到的末尾的新方式
var newArr=arr.concat(值1,arr1...);
特殊:
1、此方法不修改原数组,只会返回一个新数组
2、此方法传参支持数组参数,并且会悄悄的打散这个数组,单独传入
3、截取子数组:从starti位置截取到endi+1位置的元素,组成一个新数组
var subArr=arr.slice(starti,endi+1)
特殊:
1、此方法不修改原数组,只会返回一个新数组
2、含头不含尾
3、第二实参可以省略:从starti截到末尾
第一实参也可以省略:从头截到尾 - 昨天按值传递(浅拷贝)
深拷贝:复制了一个副本给对方
4、支持负数参数,-1代表倒数第一个
4、删除、插入、替换:
删除:var dels=arr.splice(starti,n);//从starti开始删除n个
特殊:此方法其实也有返回值,所有删除的元素组成的一个新数组
插入:arr.splice(starti,0,值1,...);//从starti开始删除0个,插入了新元素
特殊:原来starti位置的元素以及后续元素都会被向后移动
替换:var dels=arr.splice(starti,n,值1,...);
特殊:插入的个数和删除的个数可以随意
5.翻转数组:arr.reverse(); - 没用
6、排序:两种方式:
1、鄙视题:冒泡排序:把数组中的每一个数字取出来,前一个和后一个进行比较,如果前一个>后一个,两者就要交换位置:
公式:
var arr=[13,25,4,3675,12,23,3,215,2,1,42,4,65,473,2431,123];
for(var j=0;j<arr.length-1;j++){
for(var i=0;i<arr.length-(j+1);i++){
if(arr[i]>arr[i+1]){
var m=arr[i];
arr[i]=arr[i+1];
arr[i+1]=m;
}
}
}
console.log(arr);
2、正式开发中:数组API提供的排序
arr.sort();
特殊:1、默认按照字符串按位PK每个字符的unicode号排序
2、按照数字排序:
arr.sort(function(a,b){//回调函数:不需要我们程序员调用的函数:悄悄的带有循环,提供了两个形参:a是后一个数,b是前一个数
return a-b;
})
//return a-b:如果a>b,返回是一个正数
// 如果a<b,返回是一个负数
// 如果a==b,返回是一个0,sort根据你反复的结果,来判断两者要不要交换位置
3、降序排列:
arr.sort(function(a,b){//回调函数:不需要我们程序员调用的函数:悄悄的带有循环,提供了两个形参:a是后一个数,b是前一个数
return b-a;
})
强调:JS中只有数组可以排序,以后我们见到网页上任何具有排序功能的案例,底层一定都是一个数组
7、栈和队列:4个API:添加元素和删除元素的新方式
栈:一端封闭,只能从另一端进出的操作
开头进:arr.unshift(值1,...);
开头出:var first=arr.shift();//一次只能删掉一个,并且会返回删除的元素
缺点:每一次进出都会修改其他人的下标
结尾进:arr.push(值1,...);
结尾出:var last=arr.pop();//一次只能删掉一个,并且会返回删除的元素
优点:不会影响到其他元素的下标
队列:只能从一端进入,另一端出:
开头进:arr.unshift(值1,...);
结尾出:var last=arr.pop();//一次只能删掉一个,并且会返回删除的元素
结尾进:arr.push(值1,...);
开头出:var first=arr.shift();//一次只能删掉一个,并且会返回删除的元素
8.二维数组:数组中的值再次引用了一个数组
何时使用:在一个数组内在此细分内容
1、创建:
var arr=[
["张三丰",128,3500],
["张翠山",30,4500],
["张无忌",18,5500]
];
2、访问:arr[r][c];
特殊:面试中:
列下标越界:返回undefined
行下标越界:报错:undefined不能使用[]
3、遍历二维数组:必然需要两个循环嵌套:外层循环控制行,内层循环控制列
for(var r=0;r<arr.length;r++){
for(var c=0;c<arr[r].length;c++){
console.log(arr[r][c]);
}
}
#String的概念
string:字符串:多个字符组成的【只读】字符【数组】
1、为什么字符串也可以叫数组呢?
和数组有共同点:
1、支持下标 - 获取某个字符
2、支持length - 字符的长度
3、遍历
4、数组不修改原数组的API,字符串也可以使用(concat、slice)
不同点:数组修改原数组的API,字符串都不可以使用,但是字符串也有很多属于自己的API(明天)
2、只读:字符串中的所有的API都不会修改原字符串,只会返回新字符串
3、***引用类型的对象:11个
String(字符串) Number(数字) Boolean(布尔) - 具有包装类型
Array(数组) Function(函数) Math(数学) Date(日期) RegExp(正则) Error(错误) Object(面向对象)
Global - 全局对象:在浏览器端被window对象给代替了:window对象可以省略不写出来
包装类型:将原始类型的值变为一个引用类型的对象
为什么:前辈们发现字符串/数字/布尔经常都会被拿来使用,所以提前提供了包装类型封装为一个引用类型的对象,提供我们一些属性和方法(便于程序员操作)
何时使用:只要在你试图用原始类型的值去调用属性或者方法时,会自动套上包装类型
何时释放:属性或方法调用完毕后,包装类型自动释放
为什么undefined和null不能使用.:不具有包装类型,没有任何的属性和方法
String API:
1、转义字符串:\
作用:3个
1、字符串中如果出现了和字符串冲突的符号,可用\将其转义为原文
\" \'
2、特殊功能:
换行:\n
制表符:\t
3、*可以书写unicode号 表示一个字
\uXXXX
汉字的第一个字:4e00
汉字的最后一个字:9fa5
2.转换大小写:【统一的】转为大写或小写,再比较,忽略大小写
大写:var newStr=str.toUpperCase();
小写:var newStr=str.toLowerCase();
3、获取字符串中指定位置的字符的ascii码
var ascii=str.charCodeAt(i);
通过ascii码转回原文
var 原文=String.fromCharCode(ascii);
4、检索字符串:检查索引/下标:从starti位置开始找右侧的第一个关键字的下标
作用:判断有没有
var i=str/arr.indexOf("关键字",starti);
特殊:1、starti可以省略,如果省略则从0开始
2、返回值:找到了,返回第一个字符的下标
***没找到,返回-1,其实我们根本不关心下标是几,只关心下标是不是-1,-1代表没找到,不是-1代表找到了
3、数组也可以使用此方法
4、鄙视题:找到所有关键字的位置
var str="no zuo no die no can no bibi";
var i=-1;
while((i=str.indexOf("no",i+1))!=-1){
console.log("找到了:"+i);
}
5、拼接字符串:var newStr=str.concat(str1,str2...) 还不如 +运算
6、截取字符串:3个
1、**var subStr=str/arr.slice(starti,endi+1);
2、var subStr=str.substring(starti,endi+1);//不支持负数参数
3、*var subStr=str.substr(starti,n);//截取的个数,不必考虑含头不含尾
7、替换字符串:需要有了正则表达式才会牛逼
var newStr=str.replace("关键字"/正则表达式,"新内容");
8、切割/分割字符串:作用:str <=> arr
var arr=str.split("自定义切割符");
特殊:
1、切割符可以自定义,切割过后返回一个数组,数组中不再包含切割符
2、如果传入的切割符是一个"",每一个字符都会被切开