目录

1.cookie sessionStorage localStorage 区别

2.跨域是什么?如何解决跨域问题?

3.JS数据类型有哪些,区别是什么?

4.对闭包的理解

5.promise是什么与使用方法

6.BFC


1.说一说cookie sessionStorage localStorage 区别?

数据存储位置:都是浏览器的本地存储。

生命周期:cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除

存储大小:cookie的存储空间比较小,大概4KB;SessionStorage、 LocalStorage存储空间比较大,大概5M

写入方式:cookie由服务器端写入的,而SessionStorage、 LocalStorage都由前端写入的

数据共享:Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面

发送请求时是否携带:在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、 LocalStorage不会

应用场景:Cookie一般用于存储登录验证信息SessionID或者token,LocalStorage常用于存储不易变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能

2.说一说跨域是什么?如何解决跨域问题?

跨域:当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,就说该接口跨域了。

跨域限制的原因:浏览器为了保证网页的安全,出的同源策略(协议,域名,端口都相同,就是同源, 否则就是跨域)。

跨域解决方案

cors:目前最常用的一种解决办法,通过设置后端允许跨域实现。
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader("Access-Control-Allow-Methods", "GET, PUT, OPTIONS, POST");

node中间件、nginx反向代理:跨域限制的时候浏览器不能跨域访问服务器,node中间件和nginx反向代理,都是让请求发给代理服务器,静态页面面和代理服务器是同源的,然后代理服务器再向后端服务器发请求,服务器和服务器之间不存在同源限制。

JSONP:利用的原理是script标签可以跨域请求资源,将回调函数作为参数拼接在url中。后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文档类型,应该设置成javascript。

Vue的proxy:前端配置一个代理服务器(proxy)代替浏览器去发送请求:因为服务器与服务器之间是可以通信的不受同源策略的影响。
postmessage:H5新增API,通过发送和接收API实现跨域通信。

跨域场景:前后端分离式开发、调用第三方接口

3.说一说JS数据类型有哪些,区别是什么?

共有八种,分为基本数据类型和引用数据类型。基本:Number、String、Boolean、Null、undefined、bigInt、Symbol;引用:Object,对象,数组,正则,日期,Math数学函数都属于Object

存储方式: 基本数据类型是直接存储在栈中的简单数据段,占据空间小,使用频繁。引用数据类型存储在堆内存中,占据空间大。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体

Symbol是ES6新出的一种数据类型,特点是没有重复的数据,可以作为object的key。数据的创建方法Symbol(),因为它的构造函数不够完整,所以不能使用new Symbol()创建数据。由于Symbol()创建数据具有唯一性,所以 Symbol() !== Symbol(), 同时使用Symbol数据作为key不能使用for获取到这个key,需要使用Object.getOwnPropertySymbols(obj)获得这个obj对象中key类型是Symbol的key值。

let key = Symbol('key');
let obj = { [key]: 'symbol'};
let keyArray = Object.getOwnPropertySymbols(obj); // 返回一个数组[Symbol('key')]
obj[keyArray[0]] // 'symbol'

BigInt也是ES6新出的一种数据类型,特点是数据涵盖的范围大,能够解决超出普通数据类型范围报错的问题。
使用方法:
-整数末尾直接+n:647326483767797n
-调用BigInt()构造函数:BigInt("647326483767797")

注意:BigInt和Number之间不能进行混合操作

4.说一说你对闭包的理解?

当一个嵌套的内部函数引用了嵌套的外部函数的变量时,就产生了闭包,闭包存在于嵌套的内部函数中。

形成原理:作用域链,当前作用域可以访问上级作用域中的变量

作用:(1)使用函数内部的变量在函数执行完后仍然存活在内存中(延长了局部变量的生命周期)

(2)让函数外部可以操作(读写)到函数内部的数据(变量/函数)。按照面向对象的概念,闭包就是暴露一个方法,以供外部可以访问内部的变量

生命周期:产生:在嵌套内部函数定义执行完时就产生了(不是在调用时)

死亡:在嵌套的内部函数成为垃圾对象时

带来的问题:由于垃圾回收器不会将闭包中变量销毁,于是就造成了内存泄露,内存泄露积累多了就容易导致内存溢出。

应用:防抖节流

5.说一说promise是什么与使用方法?

Promise是异步编程的解决方案,解决了回调地狱(嵌套多层的回调函数)的问题,让代码的可读性更高,更容易维护。Promise是ES6提供的一个构造函数,可以使用Promise构造函数new一个实例,Promise构造函数接收一个函数作为参数,这个函数有两个参数,分别是两个函数 `resolve`和`reject`,`resolve`将Promise的状态由等待变为成功,将异步操作的结果作为参数传递过去;`reject`则将状态由等待转变为失败,在异步操作失败时调用,将异步操作报出的错误作为参数传递过去。实例创建完成后,可以使用`then`方法分别指定成功或失败的回调函数,也可以使用catch捕获失败,then和catch最终返回的也是一个Promise,所以可以链式调用。

使用方法:new Promise((resolve,reject) => { resolve(); reject(); })里面有多个resovle或者reject只执行第一个。如果第一个是resolve的话后面可以接.then查看成功消息。如果第一个是reject的话,.catch查看错误消息。Promise的链式编程可以保证代码的执行顺序,前提是每一次在then做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据。

6.说一说BFC

块级格式化上下文,是Web页面一块独立的渲染区域,内部元素的渲染不会影响边界以外的元素,可以用于清除浮动。

BFC布局规则:1.内部盒子会在垂直方向一个接一个地放置。2.Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会重叠。3.每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。4.BFC的区域不会与float box重叠。5.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。6、计算BFC的高度时,浮动元素也参与计算。

BFC形成的条件`float `设置成 `left `或 `right` ;`position `是`absolute`或者`fixed` ;`overflow `不是`visible`,为 `auto`、`scroll`、`hidden` ;`display`是`flex`或者`inline-block` 等。

BFC的方式都能清除浮动,但是常使用的清除浮动的BFC方式只有`overflow:hidden`,原因是使用float或者position方式清除浮动,虽然父级盒子内部浮动被清除了,但是父级本身又脱离文档流了,会对父级后面的兄弟盒子的布局造成影响。如果设置父级为`display:flex`,内部的浮动就会失效。所以通常只是用`overflow: hidden`清除浮动。