数组的基础
创建数组
- 直接量:var arr=[值1,....];
- 构造函数:var arr=new Array(值1,....);
hash(关联)数组:下标是可以自定义的
为什么要用hash数组:因为索引数组的小标无具体的意义,不便于查找
如何使用:
1、创建:2步
- 先创建一个空数组:var arr=[];
- 为数组添加自定义下标并且赋值:arr["自定义下标"]=新值;
2、访问
arr["自定义下标"];
3、强调:
hash数组的length会失效,永远为0.
遍历hash数组,不能再使用for循环了,必须使用for in循环.
语法:
for(var i in arr){
i->下标
arr[i]->当前次元素
}
4、hash数组的原理
hash算法:
- 将字符串,计算出一个尽量不重复的数字(地址值)
- 如果字符串内容相同,则计算出来的数字也一定相同
- 添加元素:js解释器会将自定义下标交给hash算法,得到一个数字(地址值),直接将你要保存的数据放到此地址之中保存。
- 获取元素:js解释器会将指定的下标再次交给hash算法,得到了一个和当初保存时完全一样的数字(地址值),通过此地址值就可以找到当初保存的数据了,取出来使用
5、拓展
JS里面一切东西都是对象,万物皆对象,除了undefined和null,【一切对象的底层都是hash数组】
数组的API
1、arr to str:
- var str=arr.join("自定义连接符");
- 固定套路:2个:
1、将数组里面的内容拼接为一句话/单词 - 无缝拼接,其实就是拼接了一个空字符串
2、将数组拼接为DOM页面元素
var arr=["-请选择-","北京","南京","西京","东京","重庆"];
var str=""+arr.join("")+"";
sel1.innerHTML=str;
2、拼接数组:添加元素的新方式
语法:var newArr=arr.concat(新值1,arr1,...);
将传入的实参全部拼接到数组的尾部。
特殊:
- 不修改原数组,只会返回一个新数组
- concat支持传入数组参数,悄悄将的你传入的数组打散为单个元素再拼接
3、截取子数组:只想要取出数组的某一部分使用
根据你传入的开始下标一直截取到结束下标
语法:var subArr=arr.slice(starti,endi+1)
特殊:
- 不修改原数组,只会返回一个新数组
- 含头不含尾
- endi可以省略不写,如果不写,则从starti截取到末尾
- starti和endi都可以省略不写,那么从头到尾完整的赋值一份,此操作也叫做深拷贝!复制了一个副本给对方,两者不会相互影响
- 支持负数参数,-1代表倒数第一个
4、删插替:
删除:var dels=arr.splice(starti,n); n代表你要删除几个.删除的数据有一个返回值,如果要用的话可以用一个数组将其装住。
插入:var dels=arr.splice(starti,0,新值1,...);
特殊:
- 原starti位置的元素以及后续元素都会被向后移动
- 尽量不要插入一个数组,会导致我们的数组一些是一维,一些是二维,导致遍历的时候极不方便
替换:var dels=arr.splice(starti,n,新值1,...); 插入的元素和删除的元素,个数不必相等
5、翻转数组:arr.reverse();
6、数组的排序
数组的API:arr.sort();
默认:将数组中的元素转为字符串,然后再按位PK每个字符的unicode号(ASCII码)
1、希望按照数字升序排序:
arr.sort(function(a,b){
return a-b;})//a是后一个元素,b是前一个
2、希望按照数字降序排序:
arr.sort(function(a,b){
return b-a;})
7、栈和队列:添加元素和删除元素的新方式
栈:其实就是数组,只不过是一端封闭,只能从另一端进出
- 开头进: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、新的6组API:
1、判断:2个,判断的结果一定是一个布尔值
- every:每一个,要求所有的元素都满足条件,结果才为true,只要有一个不满足则为false,非常类似于我们以前学的&& var bool=arr.every(function(val,i,arr){return})
- some:有一些,要求只要有一个元素满足,则为true,全部不满足才为false,非常类似于我们以前学的|| var bool=arr.some(function(val,i,arr){return 判断条件;})
2、遍历:拿到数组中的每个元素做相同 或 相似的操作
- forEach - 直接修改原数组: arr.forEach(function(val,i,arr){操作})
- map - 不修改原数组,返回一个新数组
- var newArr=arr.map(function(val,i,arr){return 操作;})
3、过滤和汇总:
过滤:筛选出你需要的部分,但是和现实不太一样,原数组是不会变化的! var subArr=arr.filter(function(val,i,arr){return 判断条件;}) 汇总: var sum=arr.reduce(function(prev,val,i,arr){return prev+val;})
9、箭头函数,专门简化一切的匿名回调函数:
公式:function去掉,()和{}之间添加一个=>,如果形参只有一个,那么()可以省略,如果函数体只有一句话,那么{}省略,如果函数体只有一句话并且是return,那么return和{}一起省略
2、二维数组:数组的元素,又引用着另一个数组
创建:
var arr=[
["",,],
["",,],
["",,]];
访问:arr[行下标][列下标];
2、String的概念:
什么是字符串:多个字符组成的【只读】字符【数组】 、字符串中的个数:
- str.length;
- 获取字符串中的某个字符:str[i];
- 遍历字符串
- 所有数组不修改原数组的API,字符串也可以使用(concat、slice)
2、StringAPI:
1、转义字符:\
- 将字符串中和程序冲突的字符转为原文""" '''
- 包含特殊功能的符号换行:\n制表符:\t 大空格,跟敲tab效果是一样的
- 输出unicode编码的字符
汉字的第一个字:\u4e00 -> ascii码:19968
汉字的最后一个字:\u9fa5 -> ascii码:40869
2、大小写转换:将字符串中每个英文字符统一的转为大写 或 小写
var 大写=str.toUpperCase();
var 小写=str.toLowerCase();
3、获取字符串中的指定位置的字符:str.charAt(i) === str[i]
4、获取字符串中的指定位置的字符的ASCII码:
var ascii=str.charCodeAt(i);
通过ASCII码转回原文
var 原文=String.fromCharCode(ascii);
5、检索字符串:检查索引 - 检查下标,获取关键字的下标
var i=str/arr.indexOf("关键字",starti); 用来判断数组内有没有这个关键字,只关心反不返回-1.
6、拼接字符串:var newStr=str.concat(新字符串,...) === 还不如+运算
7、截取字符串:3个
- var newStr=str/arr.slice(starti,endi+1);//和数组的用法一模一
- str.substring(starti,endi+1);//几乎和slice一样,但是不支持负数参数
- str.substr(starti,n);//n代表截取的个数,不必考虑含头不含尾
8、替换字符串
var newStr=str.replace("固定关键字"/RegExp,"新内容")
9、去掉开头结尾的空白字符
- str.trim();开头结尾
- str.trimStart();开头
- str.trimEnd();结尾
10、切割/分割字符串
- 作用:将字符串切割为数组:str<=>arr
- var arr=str.split("自定义切割符");
- 特殊:
1、切割后,切割符就不存在了
2、如果你的切割符写的就是一个空字符串"",切散每一个字符
Math对象:专门提供了数学计算的API
- Math不需要创建,直接使用,由浏览器的JS解释器自动创建
- API:
上取整:Math.ceil(num);
下取整:Math.floor(num);
四舍五入取整:Math.round(num); 其他取整:parseInt(str)+num.toFixed(d);
num.toFixed(d);
- d代表保留的小数位数,而且也带有四舍五入的功能
- 解决浏览器带来的舍入误差,计算机很笨,但是他的记忆力很强,而且速度很快,笨在何处?比如:2-1.6===0.3999999999999
- 返回的结果是一个字符串,建议搭配parseFloat使用
乘方和开方
- 乘方:Math.pow(底数,幂) === ES9提供了简化:底数**幂
- 开方:Math.sqrt(num);//只能开平方
最大值和最小值
- var max/min=Math.max/min(a,b,d,c,e,f,g...);自动在你传入的数字中找到最大值或最小值。
- 不支持数组参数
解决方法:Math.max/min.apply(Math,arr);//apply具有打散数组的功能
绝对值:把负数变成整数
Math.abs(num)
随机数:Math.random(); - 在0~1之间取一个随机小数
公式:parseInt(Math.random()*(max-min+1)+min);
Date对象
1、创建
- 创建当前时间:var now=new Date();
- 创建一个自定义时间:var birth=new Date("yyyy/MM/dd hh:mm:ss");创建一个自定义时间:
- var birth=new Date(yyyy,MM-1,dd,hh,mm,ss);//修正月份,从0~11月,0代表1月
- 复制一个日期:为什么:日期的所有的API都是直接修改原日期的,无法获得修改之前的日期所以,在执行API之前都要先进行一次复制,然后再操作复制后的日期var end=new Date(start);
2、操作
- 两个日期对象之间可以相减,得到一个毫秒差(大-小),换算出自己想要的任何一部分 - 日期的本质其实就是保存了一个毫秒数(做出倒计时的关键
- API:
年月日星期:FullYear Month Date Day
时分秒毫秒:Hours Minutes Seconds Miiliseconds 每一个分类都有一对getXXX/setXXX - 取值范围:日期还会自动进制 FullYear - 当前年份的数字Month - 0-11 Date - 1-31Hours - 0-23 Minutes、Seconds:0-59Day:0~6,0代表星期天 任何人都可以set,唯独Day没有set操作
- 如果希望对某个分类进行加减操作的话date.setXXX(date.getXXX()+/-n)
- 格式化日期为本地字符串:date.toLocaleString();
3、定时器:
- 周期性定时器:每过一段时间就会执行一次,先等再做,会反复执行,需要自己写停止才能停止 开启:timer=setInterval(callback,间隔毫秒数); 停止:clearInterval(timer);
- 一次性定时器:等待一段时间,执行一次就结束了
开启:timer=setTimeout(callback,间隔毫秒数); 停止:clearTimeout(timer);
扩展:如何使用JS创建页面元素:3步 - 深入数据渲染
- 创建空标签:var elem=document.createElement("标签名");
- 为其设置必要的属性和事件 elem.属性名="属性值"; elem.on事件名=function(){}
- 渲染到DOM树 - 上树 父元素.appendChild(elem);
BOM:Browser Object Model:浏览器对象模型
BOM的所有东西,都不需要创建,直接使用,浏览器的JS解释器会自动创建
window对象:扮演着两个角色:一个页面只有一个window
代替全局对象global,保存着全局变量和全局函数
属性:
- 获取浏览器的完整大小:outerWidth/outerHeight;
- 获取浏览器的文档显示区域(用户能看到的部分)的大小:innerWidth/innerHeight;
- 获取屏幕的完整大小:screen.width/height;
方法:
-
当前窗口打开,可以后退
HTML:用A标签
JS:open("url","_self"); -
当前窗口打开,禁止后退
history:【当前窗口】的历史记录(打开过的url),他其实可以做的事儿就是前进和后退
location:【当前窗口】的正在打开的url,而他有一个API: location.replace("新url");//叫做替换,不叫作跳转,是不会产生历史记录的,自然也就不能后退前进 -
新窗口打开,可以打开多个
HTML:用A标签
JS:open("url","_blank")
4.新窗口打开,只能打开一个
HTML:用A标签,将"traget写为自定义name"
JS:open("url","自定义name")
打开新窗口/新链接
var newW=open ("url","target","width=?,height=?,left=?,top=?");
- 如果你没有传入第三个参数,那么窗口会和浏览器融为一体,浏览器多大,窗口就多大
- 如果你传入了第三个参数,那么窗口会和浏览器分离开,独立存在
- 可以拿个变量保存住此窗口,以后用于其他操作
关闭窗口:window/newW.close();
改变新窗口的大小:newW.resizeTo(新宽,新高);
改变新窗口的位置:newW.moveTo(新x,新y);
window还提供了三个弹出框:但是具有兼容性问题
- 警告框:alert("警告文字");
- 输入框:var user=prompt("提示文字");
- 确认框:var bool=comfirm("提示文字");
window的专属事件:
- window.onload - load:加载,等待其他所有的资源加载完毕后才会执行的代码
- window.onresize - 创建如果大小发生了变化,就会触发,搭配上上面的innerWidth,我就可以判断现在窗口的大小不同,做不同的操作也就是响应式布局
- window.onscroll - 滚动事件,一旦滚动就会触发
获取滚动条当前的位置:window.scrollY
获取元素举例页面顶部有多远:elem.offsetTop/offsetLeft
本地/客户端存储技术:
cookie:存储大小只有2kb,最多只能保存30天
webStorage:存储大小只有8mb,可以永久保存
- sessionStorage - 会话级,只要浏览器一旦关闭,数据就会死亡
- localStorage - 本地级,只要你不清空他,他就永久存在
操作:
- 添加:xxxStorage.属性名="属性值";
- 读取:xxxStorage.属性名;
- 删除:xxxStorage.removeItem("属性名");
- 清空:xxxStorage.clear();