前端 - JS

147 阅读12分钟

数据类型

  • 基本数据类型: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
            }
        }
    }

生产环境通过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才能拿到数据