数组的基础
索引数组:下标都是由数字组成的数组
索引数组:下标都是无意义的,不便于查找
hash(关联)数组: 下标可以自定义
创建:
1.先创建一个空数组: var arr=[];
2.为数组添加自定义下标并赋值: arr["name"]="石昊";
访问:arr["自定义下标"];
强调:hash数组的length会失效,永远为0
遍历hash数组:使用for in循环,它不需要设置从哪开始,到哪结束,纯自动化,专门为遍历hash数组而存在
语法:
for(var i in arr){
arr[i]; // 当前次元素
}
不止能遍历hash数组,也能遍历索引数组
一切对象的底层都为hash数组,除了undefined 和 null
hash数组原理:
hash算法:将字符串,计算出一个尽量不重复的数字(地址值)字符串内容相同,则计算出来的数字也一定相同。
添加元素:js解释器会将自定义下标交给hash算法,得到一个数字(地址值),直接将你要保存的数据放到此地址之中保存。
获取元素:js解释器会将指定的下标再次交给hash算法,得到了一个和当初保存时完全一样的数字(地址值),通过此地址值就可以找到你当初保存的数据了,取出来使用了
数组的API
arr to str: var str=arr.join("自定义连接符")
固定套路:
1.将数组里面的内容拼接成一句话/单词 - 无缝连接 ,就是拼接了一个空字符串
var arr["h","e","l","l","o"," ","w","o","r","l","d"]
console.log(arr.join(""))
2.将数组拼接为DOM页面元素
var arr=["-请选择-","北京","南京","西京","东京","重庆"]
var str="<option>"+arr.join("</option><option>")+"</option>"
select.innerHTML=str
拼接数组:添加元素的新方式,将你传入的实参全部拼接到数组的末尾
语法: var newArr=arr.concat(新值1,arr,...)
特殊:
1.不修改原数组,只会返回一个新数组
2.concat支持传入数组参数,会将传入的数组打散为单个元素再拼接
截取子数组: 只要想要取出数组的某一部分使用
根据传入的开始下标一直截至到结束下标
语法: var subArr=arr.slice(starti,endi)
特殊:
1.不修改原数组,只会返回一个新数组
2.含头不含尾
3.endi可以省略不写,如果不写,则从strati截取到末尾
4.starti和endi都可以省略,那么从头到尾完美赋值一份,此操作叫深拷贝,复制一个副本给对方,两者互不影响
5.支持负数参数,-1代表倒数第1个
删插替:
删除: var dels=arr.splice(starti,n)
特殊: 虽然他直接修改原数组,但也有返回值,返回的是被删除的数组组成的一个新数组,哪怕没有删除,也会得到一个空数组
插入: var dels=arr.splice(starti,0,新值1,...)
特殊:
1.原starti位置的元素以及后续元素都会向后移动
2.尽量不要插入一个数组,会导致数组一些是一维,一些是二维,导致遍历时不方便
替换: var dels=arr.splice(starti,n,新值1,...)
特殊:
插入的元素和删除的元素不必相等
翻转数组: arr.reverse()
数组的排序
冒泡排序:
公式:
for(var j=1;j<arr.length;j++){
for(var i=0;i<arr.length-j;i++){
if(arr[i]>arr[i+1]){
var m=arr[i+1];
arr[i+1]=arr[i];
arr[i]=m;
}
}
}
arr.sort();
默认将数组中的元素转为字符串,然后按位PK每个字符串的unicode号(ASCII码)
数字升序排序:
arr.sort(function(a,b){//此函数叫做匿名回调函数
return a-b;//a为后一个数 ,b为前一个数
});
数字降序排列:
arr.sort(function(a,b){//此函数叫做匿名回调函数
return b-a;//a为后一个数 ,b为前一个数
});
强调:
1.只要网页发现有排序功能,说明他底层一定是一个数组,js中只有数组可以排序
2.只要网页发现有随机功能,说明他底层一定使用了随机数公式
栈和队列:添加元素和删除元素的新方式
栈:其实就是数组,是一端封闭,从另一端进出
开头进: arr.unshift(新值,...)//向前添加 缺点:会导致其他元素的下标发生变化
开头出: arr.unshift()//向前删除,一次只能删除一个元素,有返回值,返回的是删除的那个元素 缺点:会导致其他元素的下标发生变化
结尾进: arr.push(新值,...)//向后添加
结尾出: arr.pop()//向后删除,一次删除一个元素,有返回值,返回的是删除的那个元素
队列:其实就是数组,只能从一端进入,从另一端出去
何时使用:按先来后到的顺序拿取数据
开头进: arr.unshift(新值,...)
结尾出: arr.pop()
开头出: arr.unshift()
结尾进: arr.push(新值,...)
周期性定时器:
开启:
timer=setInterval(function(){
操作;
},间隔毫秒数)
停止:
clearInterval(timer)
鼠标移入:
elem.onmouseover
鼠标移出:
elem.onmouseout
ES5(2014年)为数组提供的3组6个API
1.判断: 判断的结果一定是布尔值
every:每一个 要求所有元素都满足条件,结果才为true,只要有一个不满足则为false,类似于&&
var bool=arr.every(function(val,i,arr){
//val - 当前的值 i - 当前的值的下标 arr - 当前数组本身
return 判断条件;
})
some:有一些 只要有一个元素满足条件,结果就为true,全部不满足则为false,类似于||
var bool=arr.every(function(val,i,arr){
//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 subArr=arr.reduce(function(prev,val,i,arr){
return prev+val;
})
箭头函数:专门简化一切的匿名回调函数
公式: function 去掉,()和{}之间添加一个=>如果形参只有一个,那么()可以省略,如果函数体只有一句话,那么{}省略,如果函数体只有一句话并且是return,那么return和{}一起省略
二维数组:数组的元素,又引用着另一个数组.
何时使用:在一个数组内,再次细分每个分组
创建:
var arr=[[],[],[],[],[],...];
访问: arr[行下标][列下标];
列下标越界,返回undefined
行下标越界,返回一个报错
遍历二维数组,必然两层循环,外层控制行,内层控制列
for(var r=0;r<arr.length;r++){
for(var c=0;c<arr[r].length;c++){
console.log(arr[r][c]);
}
}
String的概念
String的API:
转义字符: \
1.将字符串中和程序冲突的字符转为原文
"\"" '\''
2.换行:\n
制表符:\t 大空格 跟tab效果一样
3.输出unicode编码的字符
汉字的第一个字:\u4e00 ascii码:19968
汉字的最后一个字:\u9fa5 ascii码:40869
大小写转换:
var 大写:str.toUpperCase()
var 小写:str.toLowerCase()
获取字符串中指定位置的字符
str.charAt(i) === str[i]
获取字符串中指定位置的字符的ASCII码:
var ascii=str.charCodeAT(i)
通过ASCII码转为原文
var 原文=String.fromcharCode(ascii)
检索字符串:检查索引 - 检查下标,获取关键字的下标
var i=str/arr.indexof("关键字",starti);
starti可以省略,默认从0位置开始查找
强调:数组也能使用此方法,老IE(8以前)的数组没有此方法
var str=" "
var index=-1
while(index=str.indexof("关键字",index+1))!=-1{
console.log("找到了关键字",下标为:""+index)
}
拼接字符串:
var newstr=str.concat(新字符串,...) === +运算
截取字符串:
var newstr=str/arr.slice(starti,endi+1)
var newstr=str.substring(starti,endi+1)
替换字符串:
var newstr=str.replace("固定关键字"/RegExp,"新内容")
去掉开头结尾空格字符:
str.trim()
str.trimStart()
str.trimEnd()
切割/分割字符串:
作用:将字符串切割为数组
var arr=str.split("自定义切割符");
特殊:
1.切割后,切割符就不存在了
2.如果你的切割符是一个空字符串"",切散每一个字符
如何使用JS创建页面元素: - 深入数据渲染
1.创建空标签:
var elem=document.createElement("标签名")
2.为其设置必要的属性和事件
elem.属性名="属性值"
elem.on事件名=function(){}
3.渲染到DOM树 - 上树
父元素.appendChild(elem)
Math对象:
专门提供了数学计算的API
强调:Math 不需要创建,直接使用
属性:Math.PI
Math对象的API
取整:
1.上取整:超过一点点就取下一个整数 Math.ceil(num);
2.下取整:无论超过多少,省略小数点部分 Math.floor(num)
3.四舍五入取整: Math.round(num)
num.toFixed(d)
优点:
1.d代表保留的小数位数,而且也有四舍五入的功能;
2.解决浏览器带来的舍入误差
缺点:
返回的结果是一个字符串,建议和perseFloat一起使用
乘方和开方:
乘方:Math.pow(底数,幂) === 简化:底数**幂
开放:Math.sqrt(num); - 只能开平方
最大值和最小值:
var max/min=Math.max/min(a,b,c,d,...)
默认不支持数组参数
固定用法:
Math.max/min.apply(Math,arr)
绝对值: 把负数变成正数
Math.abs(num) == *-1
随机数:
公式: parseInt(Math.random()*(max-min+1)+min);
Date对象 - 日期对象
创建:
1.创建当前时间
var now=new Date()
2.创建一个自定义时间
var birth=new Date("YYYY/MM/DD h:m:s")
var birth=new Date(YYYY,MM-1,DD,h,m,s)
3.复制一个日期
var end=new Date(start)
两个日期对象之间可以相减,得到一个毫秒差(大-小)
获取时间的毫秒数:date.getTime()
Date对象的API
分量:时间的单位
年/月/日/星期: FullYear/Month/Date/Day
时/分/秒/毫秒: Hours/Minutes/Seconds/Milliseconds
获取: getxxx
设置: setxxx
特殊:
取值范围: 日期会自动进制
FullYear - 当前年份的数字
Month - 0 ~ 11
Date - 1 ~ 31
Hours - 0 ~ 23
Minutes - 0 ~ 59
seconds - 0 ~ 59
Day - 0 ~ 6 0代表周日
任何都能set,除了Day没有set操作
对某个分量进行加减操作
date.setxxx(date.getxxx() +/- n)
格式化日期为本地字符串
date.toLocaleString()// 具有兼容问题,一般会选择自己封装一个format函数来进行格式化
定时器
周期性定时器
开启: timer=setInterval(callback,间隔毫秒)
关闭: clearInterval(timer)
一次性定时器
开启:setTimeout(callback,间隔毫秒)
关闭 clearTimeout(timer)
两个定时器,看似不同的操作,底层是一样的,可以两者相互转换
BOM:Brower Object Model - 浏览器对象模型
window对象
1.代替全局对象global,保存着全局变量和全局函数
2.指代当前窗口本身
属性: 专门来获取大小
1.获取浏览器完整大小:outerWidth/outerHeight
2.获取浏览器的文档显示区域(用户能看到的部分)的大小:interWidth/interHeight
3.获取屏幕的完整大小:screen.width/height
方法: 打开链接的新方式
1.当前窗口打开,可以后退
HTML:<a href="">内容</a>
JS:open("url","_self")
2.当前窗口打开,禁止退后,使用场景:电商网站结账后禁止后退
HTML做不到,只有js可以
history:[当前窗口]的历史记录(打开过的url),可以前进和后退
location:[当前窗口]正在打开的url. API:location.replace("新"url)
3.新窗口打开,可以打开多个
HTML:<a href=""target="_blank">内容</a>
JS:open("url","_blank")
4.新窗口打开,只能打开一个,使用场景:电商网站,只允许用户打开一个结账页面
HTML: <<a href=""target="自定义name">内容</a>
JS:open("url","自定义name")
a标签的用途:
跳转
锚点
下载:<a href="xx.exe/zip/rar/7z"></a>
打开:<a href="xx.txt/jpg/png/7z"></a>
JS:<a href="javascript:js代码"></a>
打开新窗口/新链接:
var newW=open("url","target",width=?,height=?,left=?,top=?)
特殊:
1.如果没有传入第三个参数,窗口会和浏览器融为一体,浏览器多大,窗口就多大
2.如果传入第三个参数,窗口会和浏览器分离开,独立存在
3.可以用变量保存住此窗口,用于其他操作
关闭窗口:
window/newW.close();
改变新窗口大小:
newW.resizeTo(新高,新宽)
改变新窗口的位置:
newW.moveTo(新X,新Y)
警告框: alert("警告文字")
输入框: var user=prompt("提示文字")
确认框: var bool=confirm("提示文字")
定时器也是window的
window的专属事件
1.window.onload
2.window.onscroll - 滚动事件,一旦滚动就会触发
获取滚动条当前位置: window.scrollY
获取元素到页面顶部的距离:elem.offsetTop/offsetLeft
3.window.onresize - 窗口大小发生变化,就会触发,搭配innerWidth,就可以判断现在窗口的大小不同,做不同的操作,他是css3媒体查询的底层原理
提交事件: form.onsubmit=function(){
return false
}
本地/客户端存储技术
cookie: 存储大小只有2kb,而且操作极其复杂,尤其需要到处切割,最多保存30天
webstorage:存储大小8mb,永久保存,而且操作非常简单
1.sessionStorage - 会话级 只要浏览器一关闭,数据就清空
2.localStorage - 本地级 只要不清空它,就永久保存
操作:
添加: xxxStorage.属性名="属性值"
读取: xxxStorage.属性名
删除: xxxStorage.removeItem("属性名")
清空: xxxStorage.clear()