一、数组
1、数组补充
1、使用构造函数创建数组时,如果new Array(num),括号里写的是数字,则默认创建一个长度为该数字的空数组,数组中数据为undefined
2、释放引用类型:将每个引用了当前引用类型的变量都释放才能将该引用类型释放干净
3、js中不是原始类型,就是引用类型(函数、数组都是)
4、js底层有一个垃圾回收器,只有在回收器的计数器(用于记录引用当前引用类型的变量数量)为0时,才会删除不要的数据
5、代码封装成函数的意义:函数中的一切变量都会自动释放
*面试题:按值传递:var a=x;var b=a;修改啊,ab改变时是否互相影响?
答:ab是否互相影响取决于传递的值的类型。
(1)如果是原始值类型,那么a传递给b的是a一个副本,此时两者的改变互不影响。
(2)如果是引用类型,那么a传递给b的是a的地址值,二者共用一个地址,两者的改变
互相影响。引用类型所占内存空间较大,无法保存在变量本地,只能保存一个地址值。
2、hash数组(关联数组)
1、数组分类
(1)索引数组:下标都是数字的数组
(2)哈希数组:下标可以自定义
2、创建步骤
(1)创建空数组:
var arr=[];
(2)为数组添加自定义下标并赋值:
arr["自定义下标"]=新值;
3、访问数组元素:
arr["自定义下标"];
4、hash数组的length永远为0
5、遍历hash数组:(使用for in 循环)
语法:
for(i in 数组名){
数组名[i];
}
for in 循环是专门为遍历hash数组存在的,无需设置开始和结束,纯自动化,
也可以用于索引数组,但最好不使用
6、hash数组的原理:
(1)hash算法:
将字符串计算出一个尽量不重复的数字(地址值)
字符串内容相同,计算出的地址值也一定相同。
(2)添加元素:
将自定义下标使用hash算法得到地址值,将数据保存到地址值处
(3)获取元素:
将指定自定义下标通过hash算法得到一个和保存时相同的地址值,取出此地址保存的数据
7、一切对象的底层都是hash数组(js中万物皆对象,除了undefined和null)
3、二维数组
1、定义:数组的元素引用着另一个数组
2、何时使用:在一个数组中,希望细分每个分类时(例如:省市二级联动)
3、创建:
var arr=[ ["分类1","","",...],
["分类2","","",...],
["分类3","","",...],
["分类4","","",...],
......
];
4、访问:arr[行下标][列下标];
ps:(1)列下标越界,返回undefined
(2)行下标越界,报错(行越界已经是undefined,undefined不能加[])
5、遍历:必然是两层循环,外层遍历行,内层遍历列
for(var r=0;r<arr.length;r++){
for(var c=0;c<arr.length;c++){
console.log(arr[r][c]);
}
}
4、数组的API
| API功能 | 语法 | 固定用法 |
|---|---|---|
| 数组转为字符串 | var str = arr.join("自定义连接符") | var str="<开始标签>"+arr.join("</结束标签><开始标签>")+"</结束标签>" |
| 数组拼接 | var newArr = arr.concat(新值1,arr1,...) | 1、不修改原数组,只返回一个新数组 2、支持传入数组,自动将穿入的数组打散再拼接 3、添加元素的新方式 4、将传入实参拼接到数组末尾 |
| 截取子数组 | var subArr = arr.slice(starti,endi) | 1、不修改原数组,只返回一个新数组 2、含头不含尾 3、endi可以省略,省略的话默认截取到末尾 4、starti也可以省略,两个实参都省略了,就从头到尾完全复制一份,也叫作深拷贝 从传入的开始下标截取到结束下标 |
| 删除 | var dels = arr.splice(starti,n) | 1、n代表删除个数 2、有返回值,返回被删除数据组成的新数组 3、直接修改原数组 4、dels用于保存返回值 |
| 插入 | arr.splice(starti,0,新值) | 1、原starti位置的元素及后续元素都向后移动 2、插入数组的话会导致本数组既有一维也有二维 3、直接修改原数组 |
| 替换 | var dels = arr.splice(starti,n,新值) | 1、n代表删除个数 2、有返回值,返回被删除数据组成的新数组 3、直接修改原数组 4、dels用于保存返回值 5、删除个数和加入个数不必相同 |
| 翻转数组 | arr.reverse(); | 不常用 |
| 数组排序 | arr.sort(); 1、数字升序排列: arr.sort(function(a,b){return a-b;}) 2、数字降序排列: arr.sort(function(a,b){return b-a;}) | 1、a表示后一个数字 2、b表示前一个数字 括号中使用的函数叫做匿名回调函数 3、a-b返回正数代表后>前,负数代表前>后,0代表二者相等默认将数组中元素转化为字符串后,按位比较每个字符的unicode号(ASCII码) |
| 栈 | 前加: var unshift(新值,...); 前减: var first = arr.shift(); 后加: arr.push(新值...); 4、后减: var last = arr.pop(); | 1、栈是数组,一端封闭,只能从另一端进出(添加和删除)优先使用最新数据 向前添加,其余元素下标都发生改变,可以加多个 3、向前删除:一次只删除一个,其余元素下标都发生改变 |
| 队列 | 前加: var unshift(新值,...); 后减: var last = arr.pop(); 后加: arr.push(新值...); 前减: var first = arr.shift(); | 队列是数组,与栈相反,一端进另一端出 |
| 判断 | every: var bool = arr.every(functiond(val,i,arr){ return 判断条件; }) some: var bool = arr.some(functiond(val,i,arr){ return 判断条件; }) | 1、val表示当前值 2、i表示当前值的下标 3、arr表示当前数组 every:每一个,所有元素都满足条件则为true有一个不满足就为false,类似与 some:一些,只要有一个元素满足就为true,所有元素都不满足则为false,类似或 |
| 遍历 | arr.forEach(function(val,i,arr){ 想做的操作; }) var newArr = arr.map(function(val,i,arr){ return 想做的操作; }) | 1、遍历是指获取数组中所有元素进行相同或相似的操作 2、forEach直接修改原数组 3、map不修改原数组,返回一个新数组 |
| 过滤 | var newArr = arr.filter(function(val,i,arr){ return 过滤条件; }) | 过滤不改变原数组,只筛选需要的元素 |
| 汇总 | var result = arr.reduce( function(prev,val,i,arr){ return prev + val; },基础值) | 1、prev指的是当前元素之前所有的和 2、val指的是的是当前元素 |
*笔试题:将数组中的内容拼接为一句话/一个单词
无缝拼接,实际上就是拼接一个空字符串("")
答:var arr=["h","e","l","l","o","","w","o","r","l","d"];
var str=arr.join("");
console.log(str);
将数组拼接为DOM页面元素(也就是数据渲染页面)
var arr=["-请选择-","北京","南京","西京","东京"]; //取数据
var str="<option>"+arr.join("</option><option>")+"</option>";//数组拼接为页面标签字符串
sel.innerHTML = str; //innerHTML可以识别标签
5、ES6箭头函数
用于简化一切匿名回调函数
用法:将function去掉,在()和{}之间使用=>,只有一个形参时,()可以省略;函数体只有一句话时,{}可以省略,函数体只有一句话并且是return时,return和{}都可以省略。
二、引用/对象类型
| 引用对象类型 | 特殊点 |
|---|---|
| String 字符串 Number 数字 Boolean 布尔 | 1、字符串、数字、布尔既是原始类型又是包装类型 2、包装类型:专门用于将原始类型的值封装为引用类型 3、原因:原始类型没有属性和方法,不支持做任何有关属性和方法的操作,但此三类常被用于操作,因此前辈们提供了此三类的包装类型(属性和方法) 使用:试图使用它们调用属性和方法时,自动包装 释放:方法调用完毕,自动释放包装类型 |
| Array 数组 | |
| Function 函数 | |
| Date 日期 | |
| Math 数学 | |
| RegExp 正则 | 用于验证(如邮箱格式、密码格式、电话号码等) |
| Error 错误 | |
| Object | 面向对象的开发方式 |
| Global | 全局对象 1、在浏览器中被window对象代替,自然保存全局变量和函数,window可省略 2、在node.js中使用Global |
三、string
1、概念
1、多个字符组成的只读字符数组
只读:不修改原字符串,返回新字符串
2、和数组的相同点
(1)字符串的字符个数:str.length;
(2)获取字符串中某个字符:str[i];
(3)遍历字符串
(4)所有数组中不修改原数组的API,字符串也可使用(如concat,slice)
3、和数组的不同点
(1)直接修改原数组的API,字符串不可使用(如排序)
(2)字符串专属API
2、String的API:只有字符串可以使用的函数
| 功能 | 语法 | 功能/特殊点 |
|---|---|---|
| 转义字符 | \ | 1、功能:将字符串中和程序冲突的字符转为原文 2、如:"我有一个"秘密"";//报错 "我有一个"秘密"";//不报错 |
| 换行 | \n | |
| 制表符 | \t | 相当于一个大的空格,敲Tab键 |
| 输出unicode编码的字符 | \u+unicode号 | \u4e00 --- 19968 \u9fa5 --- 40869 |
| 大小写转换 | 大写: var newArr = str.toUpperCase(); 小写: var newArr = str.toLowerCase(); | 1、此API用于把字符串中的每一个字符串转换为统一的大、小写 2、程序不用区分大小写的时候,统一转为大写/小写之后,再进行比较(验证码) |
| 获取字符串中指定位置的字符 | str.charAt(i) | 不如str[i]; |
| 指定字符的ASCII码和原文互相转换 | 转为ASCII: var ascii = str.charCodeAt(i); 转为原文: var str = String.fromCharCode(ascii); | |
| 检索字符串 | var i = str/arr.indexOf("关键词/字",starti); | 1、用于检查索引,检查下标,获取关键字的下标 2、从starti位置开始,查找右侧第一个关键字的第一个字符的位置 3、starti省略时,默认从0位置开始查找 4、返回值:找到了返回找到的第一个关键字第一个字符的下标 没找到返回-1 5、从返回值可以判断是否存在关键字 6、数组也能使用此方法,但由于是后期添加的,旧版浏览器不兼容 |
| 拼接字符串 | var newArr = str.concat("新字符串",...) | 一般不使用,不如 + 运算 |
| 截取字符串 | var subAtr = str/arr.slice(starti,endi+1); | 用法和数组完全一致 |
| 不常用的截取字符串方法1 | var subAtr = str.substing(starti,endi+1); | 用法和slice几乎一致,但不支持负数参数 |
| 不常用的截取字符串方法2 | var subAtr = str.substr(starti,n); | n代表截取的个数,比substring好用 |
| 替换字符串 | var newStr = str.replace("固定关键字"/正则表达式,"新内容"); | |
| 切割/分割/分隔字符串 | var arr = str.split("自定义切割符"); | 1、切割后切割符就不存在了 2、如果切割符写了"",会切散每一个字符 |
| 去掉空白字符 | str.trim()前后都去 str.trimStart()字符串前边的 str.trimEnd()字符串后边的 |
笔试题:str.indexOf默认只能取到第一个关键字的下标,如何才能获取到所有关键字的下标?
var str = "......";
var index = -1;
while(index = str.indexOf("关键字",index+1)!=-1){
console.log("找到了,下标为:" + index);
}
js创建HTML元素的步骤:
1、创建空标签:
var elem = document.createElement("标签名");
2、为其设置必要的属性和事件:
elem.属性名 = "属性值";
elem.on事件名 = function(){操作;}
3、挂载上树/页面:
父元素.appendChild(elem);
四、Math
专门提供了数学计算的API(无需创建,直接使用)
1、API
| 功能 | 语法 | 特殊点 |
|---|---|---|
| 上取整 | var num = Math.ceil(num); 例如:35.1会被取为36 | 小数位数不能超过15位,否则只能实现取整,无法向上取整 |
| 下取整 | var num = Math.floor(num); 例如:35.9会被取为35 | 无论第一位小数是否接近一,直接省略 |
| 四舍五入取整 | var num = Math.round(num); | 只看第一位小数 |
| 常用的取整方法1 | parseInt | 如果是字符串可以去掉单位 |
| 常用的取整方法2 | num = num.toFixed(d) | 优点: 1、可以四舍五入,d代表保留的小数位数 2、可以解决浏览器的舍入误差:2-1.6=0.399999 缺点:得到一串字符串,最好搭配parseInt使用 |
| 乘方 | Math.pow(底数,幂); | 简化:底数**幂 |
| 开方 | Math.sqrt(num); | 只能开平方,报用 |
| 最大值/最小值 | var max/min = Math.max/min(a,b,c,...) | 1、自动在传入的数字中比较出最大/最小值 2、本身不支持数组参数,固定用法:Math.max/min.apply(Math,数组名); 3、apply具有打散数组的功能 |
| 绝对值 | Math.abs(-1); | 负数转正 |
| 随机数 | Math.random();在0-1之间随机取一个小数 随机数公式 parseInt(Math.random()*(max-min+1)+min) | 搭配上parseInt,只能取到0,不可能取到1,取到最大值 |
笔试题:不允许使用toFixed,自己封装一个函数,由用户转入的数字和保留位数,实现四舍五入:
五、Date
日期对象,提供了操作日期和时间的API
1、创建
(1)创建一个当前日期、时间:
var now = new Date();
(2)创建一个自定义时间:
var time = new Date("yyyy/MM/dd hh:mm:ss");//常用 使用这种方式没有限制
var time = new Date(yyyy,MM,dd,hh,mm,ss);//使用这种方式,月份可写0-11,0代表1月
(3)复制一个日期:
var end = new Date(start);
(4)一种很抽象的创建时间的方法:
var time = new Date(毫秒数);
括号里不写的话,生成现在的时间,写了的话,输出计算机元年:1970年1月1日 08:00:00
加上括号里的数字之后的时间
2、使用
两个日期对象可以相减(大减小),得到一个毫秒差,可以换算出任何需要的部分,日期的本质
就是保存了一个毫秒数,做倒计时的关键
3、API
分量:时间的单位
| 分量 | 释义 | 取值范围:超过范围自动进制 |
|---|---|---|
| FullYear | 年 | 当前年份的数字 |
| Month | 月 | 0-11 |
| Date | 日 | 1-31 |
| Day | 星期 | 0-6,0代表周天,6代表周六 ***没有set方法 |
| Hours | 小时 | 0-23 |
| Minutes | 分 | 0-59 |
| Seconds | 秒 | 0-59 |
| Milliseconds | 毫秒 | --- |
每一个分量都有一对getXXX/setXXX方法,get获取,set设置
1、对某分量进行加减
date.setXXX(date.getXXX()+/-n);
2、格式化日期为字符串
date.toLocale();//具有兼容性问题,一般不使用,不如自己写
4、定时器
1、周期性定时器:
每过一段时间执行一次,先等待后执行
(1)开启:timer = serInterval(function(){},间隔时间(毫秒数));
(2)停止: clearInterval(timer);
2、一次性定时器:
等待一段时间后执行一次就结束
(1)开启:timer = serTimeout(function(){},间隔时间(毫秒数));
(2)停止: clearTimeout(timer);
六、BOM(Browser Object Model)
意为浏览器对象模型 专门用于操作浏览器 浏览器自带很多操作,BOM没有标准,但大多数一致规范,旧版IE除外
1、window对象:
(1)表示全局对象:保存全局变量和全局函数
(2)指代当前窗口本身
1、属性
1、获取浏览器完整大小:outerWidth/outerHeight
2、获取浏览器的文档显示区大小:innerWidth/innerHeight
3、获取屏幕的完整大小:screen.width/screen.height
2、方法
1、打开链接的新方式
(1)当前窗口打开,可以后退
HTML实现:<a href="url">内容</a>
js实现: open("url","_self");//写在事件里
(2)当前窗口打开,禁止后退(如电商网站结账页面,不允许后退)
history:当前窗口的历史记录,能做的就是前进/后退
location:当前窗口正在打开的url,有一个API
location.replace("新url");
替换url,不跳转,不产生历史记录,无法后退,但因为网址改变了,所以页面会变
(3)新窗口打开,可以打开多个
HTML实现:<a href="url" target="_blank">内容</a>
js实现: open("url","_blank");//写在事件里
(4)新窗口打开,只打开一个(如电商网站,只准开一个结账页面)
HTML实现:<a href="url" target="自定义name">内容</a>
js实现: open("url","自定义name");//写在事件里
窗口在底层都有一个名字,如果打开一个已经开着的窗口,先关闭再打开
(5)总结
(1)任何标签都可以实现跳转
(2)上述各方式的作用:提高用户体验感
(3)a标签的用途:
a、跳转
b、锚点
c、下载按钮:<a href="xx.exe/rar/zip/7z">下载</a>
d、打开图片和txt文档:<a href="xx.png/jpg/jpeg/gif/txt">打开图片和txt</a>
e、直接写js不用绑定点击事件:<a href="javascript:js 代码;">打开图片和txt</a>
2、打开新窗口/新链接:
(1)newW = open("url","target","width=?,height=?,top=?,left=?");//此处不加单位
(2)没有加第三个参数,浏览器和窗口融为一体,加了窗口脱离浏览器独立存在
3、关闭窗口
window/newW.close();
4、改变窗口大小
newW.resizeTo(新宽,新高);
5、改变新窗口位置
new.moveTo(新X,新Y);
6、window的三个框
(1)警告框:alert("警告文字");
(2)输入框:var user = prompt("提示文字");
(3)确认框:var bool = confirm("提示文字");
7、定时器是window的
8、事件
(1)window.onload事件:load:加载
等待其他所有资源加载完毕后才会执行的代码,放在里边的代码最后执行
(2)window.onresize事件:
窗口大小发生变化就触发,搭配判断innerWidth可以理解为js版本的css媒体查询事件
(3)window.scroll事件:滚动事件,一发生滚动就触发
a、获取滚动条当前的位置:window.scrollY;
b、获取元素到页面边缘的距离:elem.offsetTop到顶部/elem.offsetLeft到左边
9、本地/客户端存储技术
(1)cookie:已淘汰,存储大小2KB,操作麻烦,需要到处切割,最多保存30天
(2)webStorage:H5的新特性之一,存储大小8MB,永久保存
a、webStorage分类:
1、sessionStorage:会话级,浏览器一旦关闭,数据就清空
2、localStorage:本地级,不手动清空就永久存在
3、操作:
(1)添加:xxxStorage.属性名 = "属性值";
(1)读取:xxxStorage.属性名;
(1)删除:xxxStorage.removeItem("属性名");
(1)清空:xxxStorage.clear();
2.BOM的常用对象
(1) history对象:保存了当前窗口的历史记录(过去的url)
前进: history.go(1);
后退: history.go(-1);
刷新: history.go(0);
(2) location对象:保存了当前窗口正在打开的url(现在的url)
a.常识类问题:
一个url由几个部分组成?每个部分分别有什么作用?
答:一个url由五个部分组成
1.协议: https(加密)/http(未加密)/ftp(传输文件)/ws(直播)
****其中https和http属于请求-响应模式
2.主机号|IP地址|域名:域名需要购买,主机号|IP地址是免费
3.端口号:https默认端口: 443,http默认端口: 80,只有默认端口可以省略不写
4.***文件的相对路径|路由
5.查询字符串|请求消息:前端传输到后端的东西,就是form表单提交带来的东西
b.属性
1.分别获取url五个部分的内容(直接输入location对象就可全部查询)
协议:location.protocal;
域名:location.hostname;
端口:location.port;
路由:location.pathname;
请求消息:location.search;
2.跳转:
location="新url" - 替换当前窗口,可以后退
location.replace("新url") - 替换当前窗口,禁止后退
3.刷新:
location.reload();
(3)事件周期: 从事件发生,到所有事件处理函数执行完毕的全过程
3个阶段:
1、捕获阶段:由外向内,记录要发生的事件有哪些
2、目标优先触发:目标元素(当前点击的实际发生事件的元素)
3、冒泡触发:由内向外,依次执行记录着的事件
(4)获取事件对象event:
主流:会自动作为事件处理函数的第一个形参传入
IE:event; - IE的全局变量
兼容:event; - 主流和IE均可使用
得到了事件对象event可以做什么呢?
1、获取鼠标的坐标:
获取鼠标相对于屏幕的坐标:e.screenX/Y
获取鼠标相对于窗口/客户端/文档显示区域的坐标:e.clientX/Y
*获取鼠标相对于网页的坐标:e.pageX/Y
2、阻止事件冒泡:- 笔试面试中
主流:e.stopPropagation();
IE:e.cancelBubble=true;
兼容:e.cancelBubble=true;
//主流和IE均可使用
3、*****利用冒泡/事件委托 - 开发中常用,提升网页性能,事件函数也可以换为箭头函数了
优化:如果多个子元素定义了相同 或 相似的事件操作,最好只给父元素定义一次
原因:每一次绑定一个事件函数,其实都是创建了一个事件对象,
创建的事件对象越多,网站性能就越差
淘汰了this, 当前元素, 会改变
使用一个目标元素target:点击哪一个就是哪一个,不会变化的
主流:e.target;
IE:e.srcElement;
兼容:e.srcElement;//主流和IE均可使用
注意:
1.判断元素标签: xx.nodeName,标签名全是大写
2.事件处理函数写为箭头函数的时候this失效,使用e.target
4、阻止浏览器的默认行为:
比如:a标签默认就可以跳转,提交按钮可以提交表单,右键显示一个弹出框,
F12显示控制台,F11显示全屏,F5自带刷新功能
主流:e.preventDefault();
IE:e.returnValue=false;
兼容:e.returnValue=false;//主流和IE均可使用
5、新事件:
1、右键事件 - window.oncontextmenu
2、键盘事件:一般来说用于游戏开发较多+都要搭配上键盘的键码
window.onkeydown - 按住和按下,任何键盘按键都可以触发
window.onkeypress - 按住和按下,只有字母、数字、回车、空格
可以触发,其他按键不行
window.onkeyup - 松开,任何键盘按键都可以触发(比手速的游戏)
6、获取键盘的键码:
e.keyCode;
//可以获取到你按了哪个键,每个键都有自己对应的键码,不需要记忆,
使用本句输出查看或者搜索
***event可以说是BOM之中最重要的一个点,笔试面试只要考BOM多半都是event
IE:不支持HTML5和CSS3和ES5+