面试题目系列
cookie localstorage seesionstorage区别
Cookie
、SessionStorage
、LocalStorage
都是浏览器的本地存储。
它们的共同点:都是存储在浏览器本地的
它们的区别:
cookie
是由服务器端写入的,而SessionStorage
、LocalStorage
都是由前端写入的cookie
的生命周期是由服务器端在写入的时候就设置好的,LocalStorage
是写入就一直存在,除非手动清除,SessionStorage
是页面关闭的时候就会自动清除。cookie
的存储空间比较小大概4KB
,SessionStorage
、LocalStorage
存储空间比较大,大概5M
。Cookie
、SessionStorage
、LocalStorage
数据共享都遵循同源原则,SessionStorage
还限制必须是同一个页面。在前端给后端发送请求的时候会自动携带Cookie``中的数据,但是
SessionStorage、
LocalStorage`不会- 由于它们的以上区别,所以它们的应用场景也不同,
Cookie
一般用于存储登录验证信息SessionID
或者token
,LocalStorage
常用于存储不易变动的数据,减轻服务器的压力,SessionStorage
可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。
get post区别,get在不同浏览器中的最大长度
数据传递方式的区别:
GET
参数 通过url
传递; 而 POST 将数据放在 请求体(request body)
中;
GET
请求 在url
中传递的参数有长度上的限制, 而POST
请求 没有;
POST
相对于GET
更 安全,因为POST
请求 的数据在地址栏上不可见, 而GET
请求 参数直接暴露在url
中,故不能用来传递敏感信息;
本质上的区别:
GET
是用来从服务器上获得
数据, 而POST
是用来向服务器上传递
数据;
HTTP
协议 从未规定GET/POST
的请求长度限制是多少;
对GET
请求参数的限制是来源于浏览器或web 服务器,浏览器,不同的浏览器和WEB 服务器,限制的最大长度不一样, 如:IE最大长度为2083byte
;Chrome最大长度8182byte
;
下列代码输出
if(!("a" in window)) {
var a = 1;
}
alert(a);
输出underfined
,理解:
var a;
if (!("a" in window)) {
a = 1;
}
alert(a);
JS数据类型有哪些,区别是什么?
基本数据类型:Number
、String
、Boolean
、BigInt
、Symbol
、Null
、Undefined
引用数据类型:Object
总共8种
基本数据类型是直接存储在栈中的简单数据段,占据空间小,属于被频繁使用的数据。
引用数据类型是存储在堆内存中,占据空间大。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。
Symbol
是ES6
新出的一种数据类型,这种数据类型的特点就是没有重复的数据,可以作为object
的key
。
对闭包的理解?
- 内层函数引用外层函数中变量,这些变量的集合就是闭包
- 通过作用域链,当前作用域可以访问上级作用域中的变量
- .解决的问题:保存变量
- 带来的问题:内存泄露
- 闭包的应用:防抖节流
跨域是什么?如何解决跨域问题?
跨域
的概念:浏览器不能执行其它的网站的脚本,这由浏览器的同源策略造成的,也是浏览器施加安全的限制。跨域解决方案:
jsonp
程序员利用漏洞,使用script请求,只能get请求前端
proxy
后端
cors
设置请求头实现线上
Nginx
JavaScript有几种方法判断变量的类型?
typeof
(根据二进制判断),不能判断数据类型:null
和object
intance of
(根据原型链判断),原生数据类型不能判断constructor
(根据构造器判断),不能判断null
数据类型Object.prototype.toString.call()
(用Object
的toString
方法判断)所有类型数据都能判断,判断结果打印为:'[object XXX]'
css权重
!important
> 内联样式(style
) > ID选择器(id
) > 类选择器(class
) > 标签选择器
JS实现异步的方法?
回调函数、事件监听、setTimeout
、Promise
、生成器Generators/yield
、async/awit
JS变量提升?
函数
和var
声明的变量会有变量提升,js在预编译阶段会将函数和var声明的变量提升至最前面先执行,之后再按顺序执行代码块进行赋值,而let
和const
声明的变量只是创建提升,在预编译中将其创建,形成暂时性死区,不能提前访问和调用变量,只能在赋值之后进行调用和访问
map 和 forEach 的区别?
简洁说明:
map
创建新数组、map
返回处理后的值、forEach()
不修改原数组、forEach()
方法返回undefined
理解:
相同点:
都能遍历数组
中途不能被
break
打断函数中都有三个参数,当前遍历的
元素
,当前元素的索引
,原数组
。
不同:
forEach
没有返回值,也就是返回undefined
,map
会开辟新的一个内存空间,返回新的数组,这点也方便链式调用其他数组方法。
map
的效率比forEach
高
new会发生什么?
在堆内存中开辟一个空间,其中this永远指向这个实例化出来的对象
- 创建一个新对象
- 将新对象的__proto__(原型)指向构造函数的
prototype
(原型对象) - 构造函数绑定新对象的this并执行返回结果
- 判断返回结果是否为
null
,如果为null
,返回新对象,否则直接返回执行结果。
伪数组和数组的区别?
伪数组的特点:类型是
object
、不能使用数组方法、可以获取长度、可以使用for in
遍历伪数组可以装换为数组的方法:
- Array.prototype.slice.call()
- Array.from()
- […伪数组]
- 有哪些是伪数组:函数的参数
arguments
,Map
和Set
的keys()
、values()
和entires()
如何实现可过期的localstorage数据?
惰性删除、定时删除
惰性删除:
存储的数据类型是个对象,该对象有两个key,一个是要存储的value值,另一个是当前时间。获取
数据的时候,拿到存储的时间和当前时间做对比,如果超过过期时间就清除Cookie。
定时删除:
获取所有设置过期时间的key判断是否过期,过期就存储到数组中,遍历数组,每隔1S(固定时
间)删除5个(固定个数),直到把数组中的key从localstorage中全部删除。
创建ajax过程?
- 创建
XHR
对象:new XMLHttpRequest()
- 设置请求参数:
request.open
(Method, 服务器接口地址); - 发送请求:
request.send()
,如果是get请求不需要参数,post请求需要参数request.send(data)
- 监听请求成功后的状态变化:根据状态码进行相应的处理。 XHR.onreadystatechange = function () { if (XHR.readyState == 4 && XHR.status == 200) { console.log(XHR.responseText); // 主动释放,JS本身也会回收的 XHR = null; } };
function loadXMLDoc(){
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr = new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "需要请求的地址"
xhr.open('GET',url,true);
// xmlHttp.open("POST",url,true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState==4 && xhr.status==200) {
console.log(XHR.responseText) // dosomething xhr.responseText就是请求的内容
}
}
}
前端性能优化手段?
简洁:
图片压缩和文件压缩、雪碧图/精灵图、
节流防抖
、HTTP缓存
、本地缓存、Vue
的keep-alive
缓存、ssr
服务器端渲染、懒加载、对dom
查询进行缓存、将dom
操作合并
标准:
前端性能优化分为两类:一类是文件加载更快、另一类是文件渲染更快。
加载更快的方法:
- 让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩
- 减少网络请求的次数:雪碧图/精灵图、节流防抖
- 减少渲染的次数:缓存(
HTTP缓存
、本地缓存
、Vue
的keep-alive
缓存等)渲染更快的方法:
- 提前渲染:
ssr服务器端渲染
- 避免渲染阻塞:
CSS
放在HTML的head
中,JS
放在HTML的body
底部- 避免无用渲染:懒加载
- 减少渲染次数:对dom查询进行缓存、将dom操作合并、使用减少重排的标签
扩展(…)的使用场景
- 数组克隆 let a = [1,2,3];let b = […a]
- 数组合并 let a = [1,2,3];let b = [4,5,6];let c = […a,…b]
- 类数组转成真正的数组 let a = new Set([1,2,3]); let b = […a]