数据类型
- 基本数据类型:Number、String、Boolean、Null、Undefined、Symbol(ES6新增)、BigInt(ES10新增)
- Symbol是一种新的原始数据类型,表示独一无二的值。Symbol函数前不能使用new命令,否则会报错。Symbol值不是对象,所以不能添加属性。
- 引用数据类型:Object,Array、Function、Date的实例、Math数学的对象方法 基本数据类型和引用数据类型的区别:
- 基本数据类型存储在栈内存,引用数据类型存储在堆内存。
- 基本数据类型操作的是值,引用数据类型操作的是空间地址。
检测数据类型的方法
- typeof 返回一个字符串,字符串中的内容代表当前的数据类型。
- typeof只能检测基本数据类型值,不能检测引用数据类型,检测引用数据类型返回的都是'object'。 注意:typeof检测null返回的是'object'。
- instanceof 构造函数类,检测当前实例是否属于某个类的方法。
- instanceof不能检测字面量方式创建的基本数据类型值。
- instanceof检测时,只要类在当前实例的原型链上,都会返回true。
- constructor 原型有可能被扩展,导致constructor丢失,检测不准确。
- 继承的时候可能导致原型constructor发生改变。
- Object.prototype.toString.call()
- 会默认先调用toString转成字符串
- toString返回当前函数中的this对应的数据类型,返回值是['object类']
数组的方法
原数组发生改变
- push 向数组的末尾新增一项或多项
- pop 删除数组的最后一项
- unshift 向数组的开头新增一项或者多项
- shift 删除数组的第一项
- splice 数组的增删改
- 传一个参数,从索引n删除到末尾(包含n)
- 传两个参数,从索引n开始,删除m项(包含n)
- 传三个参数,从索引n开始,删除m项,用x进行替换
- sort 排序(只能对相同位数的数组进行排序)
- reverse 反转
原数组不发生改变
- slice 截取
- 传一个参数,从索引n截取到末尾
- 传两个参数,从索引n开始截取到索引m(不包含索引m对应的那一项)
- concat 数组的拼接(将两个数组合并成一个)
- join 将数组成员按照特定的字符连接到一起
- indexOf 返回找到数组成员在数组中第一次出现对应的索引位置,不存在返回 -1 。
- lastIndexOf 返回找到数组成员在数组中最后一次出现的索引位置,不存在返回 -1 。
- toString 将数组转成字符串
- map 映射,循环(必须return)映射一个新数组,原数组不发生改变
- forEach 循环(不需要return,return无效)
- filter 过滤(传入的是一个回调函数)
let ary = [12,34,56,78,90];
let newAry = ary.filter((item,index)=>item>55);
console.log(newAry);
- find 找到符合条件的第一个数组成员(传入一个回调函数,找到符合条件的就不再向下查找了。如果没有满足条件的,那么返回undefined;满足条件,返回满足条件的那一项)
let arr = [12,34,56,78,90];
let newArr = arr.find((item,index)=>item>75);
console.log(newArr);
- every 找false(返回的是一个布尔值,只要有一个返回false,函数就不会再向下执行)
let ary1 = [12,34,56,78,90];
let newAry1 = ary1.every((item,index)=>item>15);
console.log(newAry1);
- some 找true(只要找到满足条件的,就不会再向下循环了)
let arr1 = [12,34,56,78,90];
let newArr1 = arr1.some((item,index)=>item>80);
console.log(newArr1);
- includes 返回一个布尔值,存在就返回true,不存在就返回false。
let ary2 = [12,34,56,78,90];
let newAry2 = ary2.includes(56);
console.log(newAry2);
- reduce 收敛(经常用于求和,返回一个求和结果。第二个参数相当于给第一次执行的函数传给prev)
let ary3 = [12,34,56,78,90];
let newAry3 = ary3.reduce((prev,next)=>{
return prev + next;
});
console.log(newAry3);//270
字符串的方法
- 1.toUpperCase 把写字母转成大写
- 2.toLowerCase 把大写字母转成小写
- 3.charAt 通过索引获取对应的字符
- 4.charCodeAt 通过索引获取到对应的字符,根据这个字符返回其对应的unicode编码值。
- 5.substr 字符串的截取,从索引n开始,截取m项
- 6.substring 字符串的截取,从索引n开始,截取到索引m(不包含索引m对应的那一项)
- 7.split 按照特定的字符把字符串分割成数组中的每一项,返回一个数组
- 8.replace 替换
- 9.trim 去左右空格
原型链
每一个实例对象上有一个 __ proto __ 属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有 __ proto __ 属性,这样一层一层往上找的过程就形成了原型链。
小结:
- 1.每一个函数数据类型天生自带一个prototype属性,这个属性的属性值是一个对象。对象里面存储的就是当前类的实例的共有属性和方法。(对象也叫做原型)
- 2.每一个原型天生自带constructor属性,其属性值就是【当前原型所属的类】。
- 3.每一个实例天生自带一个 __ proto __ 属性,这个属性的属性值指向【当前实例所属类的原型】
new 操作符做了什么?
- 函数执行代码解析前,先创建了一个空对象。
- 让当前函数体中的this指向了这个空对象。
- 代码执行完以后,会默认return出这个this。
闭包
闭包(closure)指有权访问另一个函数作用域中变量的函数,简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。(函数执行产生不销毁的作用域,它可以保护里面的变量不受外界干扰,而且还可以保存里面的值一直存在,这种保存和保护的机制就是闭包。)
手写闭包函数
function fn(){
var num = 10;
function fun(){
console.log(num);
}
return fun;
}
var f = fn();
f();
- 优点:保护里面的变量不受外界干扰,保存里面的值一直存在。
- 缺点:会增大内存使用量,使用不当容易造成内存泄漏,闭包对脚本性能就有负面影响,包括处理速度和内存消耗。延长变量作用域、在函数的外部可以访问函数内部的局部变量,容易造成内层泄露,因为闭包中的局部变量永远不会被回收。
- 原理:利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层(也就是全局作用域),这样就形成了一个链条。
- 应用:工具库的封装、防抖节流、点击事件、鼠标移入、滚动条、定时器。
防抖和节流
- 防抖(debounce):用在高频率点击事件,触发高频函数事件后,n秒内函数只能执行一次。如果n秒内这个事件再次被触发的话,那么会重新计算时间。防抖是多次执行变成最后一次执行。
- 节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。节流是多次执行变成每隔一段时间执行。
http和https的基本概念
- http:是一个客户端和服务器端请求和应答的标准(TCP),用于从www服务器传输超文本到本地浏览器的超文本传输协议。
- https:是以安全为目标的HTTP通道,即HTTP下加入SSL层进行加密。其作用是:建立一个信息安全通道,来确保数据的传输,确保网站的真实性。
- 区别:
- http是超文本传输协议,信息是明文传输,HTTPS协议要比http协议安全。
- HTTPS是具有安全性的SSL加密传输协议,可防止数据在传输过程中被窃取、改变,确保数据的完整性(当然这种安全性并非绝对的)。
- http协议的默认端口为80,HTTPS的默认端口为443。
- http的连接很简单,是无状态的。HTTPS握手阶段比较费时,会使页面加载时间延长50%,增加10%-20%的耗电。
- HTTPS缓存不如http高效,会增加数据开销。
- HTTPS协议需要CA证书,费用较高,功能越强大的证书费用越高。
- SSL证书需要绑定IP,不能在同一个IP上绑定多个域名IPV4资源支持不了这种消耗。
HTTPS协议的工作原理
- 客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤:
- 客户端使用HTTPS url访问服务器,则要求web服务器建立ssl链接。
- web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),传输给客户端
- 客户端和web服务器端开始协商SSL链接的安全等级,也就是加密等级。
- 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥并传送给网站。
- web服务器通过自己的私钥解密出会话密钥。
- web服务器通过会话密钥加密与客户端之间的通信。
HTTP状态码
- 200 请求成功
- 301 永久重定向
- 302 临时重定向
- 304 缓存
- 400 给服务器传递的参数有问题
- 401 没有访问权限
- 404 请求地址错误
- 500 服务器的未知错误
- 503 服务器超负荷
强缓存和协商缓存
- 强缓存:给资源设置过期时间,当客户端请求资源时,会判断是否过期,如果没有过期,不需要访问服务,如果过期了,向服务器发送请求。
- 协商缓存:发送请求 -> 看资源是否过期 -> 过期,请求服务器 => 服务器对比资源是否真的过期,如果没有过期,返回304状态码,客户端使用缓存的老资源。
什么是跨域?
- 协议、域名、端口号有一个不一样就是跨域。
CORS跨域
- CORS需要浏览器和后端同时支持。IE8和IE9需要通过XDomainRequest来实现。
- CORS跨域,在服务器 Access-Control-Allow-Origin 设置允许的源地址(设置哪些域名可以访问资源,如果设置*通配符表示所有网站都可以访问资源),一般不需要前端做处理(前端最多设置xhr.withCredentials = true;允许发送请求的时候携带资源凭证)
Proxy代理
//proxy 只适用于开发阶段
devServer:{
contentBase:"./public",
inline:true,
port:8000,
proxy:{
"/api":{
target:"http://localhost:9000",
secure:false
}
}
}
- proxy代理使我们通过代理控制对另一个对象的访问。
- proxy代理只能用作于开发阶段,临时解决本地请求服务器(通常是测试服)产生的跨域问题,并不适用于线上环境。
- proxy工作原理实质上是利用 http-proxy-middleware 这个http代理中间件,实现请求转发给其他服务器。例如:本地主机A为http://localhost:3000,该主机浏览器发送⼀个请求,接⼝为/api,这个请求的数据(响应)在另外⼀台服务器B http://10.231.133.22:80 上,这时,就可以通过A主机设置webpack proxy,直接将请求发送给B主机。
生产环境通过nginx处理跨域
- 访问80端口
- server_name:配置申请的域名
- location ^~/api/ {
proxy_pass: 后端接口地址
add_header:解决跨域的参数
rewrite:删除配置前缀
}
localStorage、sessionStorage、cookie的含义
- localStorage存储的信息是永久存储在客户端(浏览器)的,除非你手动移除,卸载浏览器,没有过期时间。
- sessionStorage是会话存储,刷新页面不会清除,但是关闭页面就清除了。
- cookie会自动通过请求头发送给服务端。
cookie和localStorage的区别
- 大小限制:cookie一般浏览器允许在同一个域名下最多存4kb。localStorage可以存储5MB左右。
- 兼容性:cookie几乎可以兼容所有浏览器。localStorage是H5新增的,低版本的浏览器是不支持。
- 稳定性:cookie可以设置过期时间,但是一般情况下,没有到达设置的过期时间之前cookie都被清除了。(比如:电脑的安全卫士清除缓存垃圾的时候,就有可能把cookie清除了。浏览器中的清除浏览记录也可以清除cookie,无痕模式不能设置cookie)。
什么时候会用到本地存储?
- 记住用户名和密码(自动登录)。
- 在未登录状态下,如果加入购物车的信息一般也会存储到本地,当登录以后把存储在本地的购物车信息发送给服务端(可以实现多端共享)。
本地存储的限制
- 本地存储是受浏览器限制的,加入在谷歌浏览器下存储的数据在IE浏览器下拿不到。
- 受域的限制,不同域之间的存储是不互通的。本地存储的信息在控制台中可以直接看到各种本地存储(而且是明文存储),所以数据不敏感的数据可以进行本地存储。但是比较敏感的数据最好不要存储在本地中,如果非要存储,需要对数据做安全处理(加密)。
setItem(key,value):设置存储
getItem(key):获取存储
removeItem(key):移除存储
clear():移除全部存储 ===> 向本地存储信息都是字符串格式的,如果你想存储对象的话,要先拿JSON的方法转一下
fetch请求的缺点
- 低版本的浏览器不兼容
- fetch不接受跨域的cookie
- fetch不能发送cookie
- fetch至少需要两个then才能拿到数据