# call() apply():
俩者都是改变this的指向,在指向的作用域中调用该函数的方法并执行,
不同的是,call()的传参是多个元素依次传的,而apply()则是通过数组的形式统一传参;
<!-- bind()是调用该对象构成一个新的函数,不会立即执行 -->
# 如何进行跨域处理
jsonp,通过动态创建 script,再请求一个带参网址实现跨域通信。
缺点:JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。
cors,服务端设置 Access-Control-Allow-Origin 即可,前端无须设置,若要带 cookie 请求,前后端都需要设置。
服务器反向代理,websocket,iframe跨域、postMessage
# 事件委托
利用事件冒泡的原理,将原本子元素要执行的事件绑定到其父元素上,让父元素代其执行函数;
# 闭包
一个函数和这个函数内部能访问到的变量的总和,就是一个闭包。或者说可以访问其他函数内变量的函数,叫做闭包。
闭包的作用
闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中
闭包好处
(1)可以用来保存一个需要持久保存的变量
(2)避免全局变量的污染
(3)可以用来定义私有属性和私有方法
(4)安全性提高
闭包坏处:
比普通函数更占内存,导致性能变差,且在ie浏览器中存在内存泄漏
闭包会造成内存泄露?
闭包不会造成内存泄漏。
内存泄露是指你用不到(访问不到)的变量,依然占居着内存空间,不能被再次利用起来。
但是闭包里面的变量明明就是我们需要的变量(lives),所以不存在内存泄漏。
这个谣言是如何来的?因为 IE。IE 有 bug,IE 在我们使用完闭包之后,依然回收不了闭包里面引用的变量
# cookie 和 session的区别
cookie是浏览器发送给服务器的一段字符串信息
session是会话,是浏览器和服务器在一段时间内的会话
cookie在浏览器上,session在服务器上
# JS阻止冒泡和取消默认事件(默认行为)
阻止冒泡:e.stopPropagation() e.cancleBubble = true W3C和IE
取消默认行为: e.preventDefault() e.returnValue = false
# 添加 删除 替换 插入到某个接点的方法
obj.appendChild()
obj.removeChild()//删除
obj.replaceChild()//替换
obj.insertBefore() //原生的 js 中不提供 insertAfter();
# 列举浏览器对象模型BOM里常用的至少4个对象,并列举 window 对象的常用方法至少5 个
对象:Window document location screen history navigator
方法:Alert() confirm() prompt() open() close()
# js中的3种弹出式消息提醒(警告窗口,确认窗口,信息输入窗口)的命令式什么?
alert confirm prompt
# 简述列举文档对象模型DOM里document的常用的查找访问节点的方法并做简单说明
Document.getElementById 根据元素 id 查找元素
Document.getElementByName 根据元素 name 查找元素
Document.getElementTagName 根据指定的元素名查找元素
# JavaScript的数据类型都有什么?
基本数据类型:String,Boolean,Number,Undefined,Null
引用数据类型:Object(Array,Date,RegExp,Function)
# iframe 的优缺点?
优点:
1. 可以实现异步刷新,单个iframe刷新不影响整体窗口的刷新
2. 可以实现跨域,方便引入第三方内容,解决加载缓慢的问题
3. 可以并行加载脚本
缺点:
1. iframe 会阻塞主页面的 Onload 事件
2. 即时内容为空,加载也需要时间
3. 没有语意
# int所占几个字节,表示的范围
int占4个字节,范围:-2^31到2^31-1
# Integer和int区别
1.Integer是int的包装类,int则是java的一种基本数据类型
2.Integer变量必须实例化后才能使用,而int变量不需要
3.Integer的默认值是null,int的默认值是0
# 为什么使用多个域名来存储网络资源会更有效?
1.CDN存储更方便
2.突破浏览器并发限制
3.节约cookie宽带
4.节约主域名的连接数,优化页面响应速度
5.防止不必要的安全问题
# http和https有什么区别?
http
http是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准,
用于从www服务器传输超文本到本地浏览器的传输协议,它可是使浏览器更加高效,使网络传输减少。
https
https是以安全为目标的http通道,简单讲是http的安全版,是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议
1. https协议需要到ca申请证书,一般免费证书比较少,因而需要一定费用
2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议
3. http和https使用的是完全不同的连接方式,用的端口也不是一样,前者是80,后者是443
4. http连接很简单,无状态;https是需要加密传输,身份认证,比较安全
# https使用上有什么注意点?
1. 不能部分部署https,应当应用于所有页面,否则会存在sessionID被拦截
2. 部署https后,将任何普遍的http请求都重定向至https的url
3. 在cookies上设置安全标记
# https和http性能有什么区别?
1. http进行tcp三次握手,而https进行tcp三次握手以及ssl握手,https的速度较http协议慢
2. https协议的计算耗时增加
# 浏览器的加载顺序以及repaint/reflow
(1)输入网址,浏览器像服务器发出请求,服务器返回html文件
(2)浏览器载入html代码,发现head标签中有一个link引用了外部css文件
(3)浏览器又发起css文件请求,服务器返回这个css文件
(4)浏览器继续载入body部分的代码,而且css文件已经拿到,开始渲染页面
(5)浏览器在代码中发现一个引用img标签的图片,开始向服务器发出请求,浏览器继续渲染后续代码,不停止等待
(6)服务器返回图片文件,由于图片占用了一定的位置,影响了后面的排版布局,因此浏览器需要返回重新渲染代码
(7)浏览器发现javascript标签,运行外部js文件,浏览器发起请求,服务器返回js文件
(8)浏览器开始解析js代码,发现js中需要隐藏代码中的块(div...),重新渲染代码
(9)如果更改页面布局和颜色搭配,浏览器重新请求css,重新渲染
# 如何理解前后端分离?
前端:负责View和Controller层。
后端:只负责Model层,业务处理/数据等。
# TCP三次握手
第一次握手:建立连接时,客户端发生syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;syn(同步序列编号)
第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),同时自己也发送一个syn包(syn=k),即syn+ack包,此时服务器进入syn_recv状态
第三次握手:客户端收到服务器的syn+ack包,向服务器发送确认包ack(ack=k+1),此包发送完毕,客户端和服务器进入established状态,完成三次握手
完成三次握手后,客户端与服务端开始传送数据
# TCP四次握手(挥手)
第一次挥手:客户端发送一个fin,用来关闭客户端到服务器端的数据传送,客户端进入fin_wait_1状态
第二次挥手:服务器收到fin后,发送一个ack,确认序号为收到的序号+1,和syn一样,一个fin占用一个序号
第三次挥手:服务器关闭与客户端a的连接,发送一个fin给客户端a
第四次挥手:客户端a发回ack报文确认,并将确认序号设置为收到序号+1
# 为什么建立协议是三次握手,关闭连接却是四次握手?
这是因为服务器端的listen状态下的socket当收到syn报文的建连请求后,它可以把ack和syn(ack起应答作用,而syn起同步作用)放在一个报文里来发送,但关闭连接时,当收到对方的fin报文通知时,它仅仅表示对方没有数据发送给你,但未必你所有的数据全部发送给对方了,所以你可以未必会马上关闭socket,也即你可能还需要发送一些数据给对方之后买发送fin报文来表示你同意现在可以关闭连接了,所有他这里的ack报文和fin报文多数情况下都是分开发送的。
# 三种禁止浏览器缓存的头字段以及设置指
Expires: 0
Cache-Control: no-cache/no-store(request+response)/private
Pragma: no-cache
# vue模块化
是从代码逻辑的角度进行划分;方便代码分层开发,保证每个功能模块的职能单一;
# Vue双向绑定的原理
Vue双向绑定就是:数据变化更新视图,视图变化更新数据
Vue数据双向绑定是通过数据劫持和观察者模式来实现的,
数据劫持,主要是通过object对象的defineProperty属性,它的目的是:当给属性赋值的时候,程序可以感知到,就可以控制改变属性值
观察者模式当属性发生改变的时候,使用该数据的地方也发生改变
<!-- # vue的双向绑定
vuejs采用数据劫持结合发布者-订阅者模式,Object.defineProperty()劫持各属性的setter和getter,数据变动时发消息给订阅者,触发监听回调
1.observe的数据对象进行递归遍历,都加上setter和getter,这样给对象赋值就会触发setter,就能监听数据变化
2.compile解析模版指令,将模版的变量替换成数据并渲染视图,将每个指令的节点绑上更新函数,添加监听数据的订阅者,数据变动就会更新视图
3.watch订阅者,是Observe和Compile的通信桥梁,属性变动dep.notice()变动时,调用自身update()方法,触发compile的绑定回调 -->
# vue的生命周期
beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
(1)beforeCreate:el和data未初始化
(2)created:完成了data数据的初始化,el未初始化
(3)beforeMount:el和data已经初始化,还未渲染好,只是使用虚拟DOM把坑先占住。
(4)mounted:完成挂载,已经渲染完成。
# Vuex整个触发过程(actions,state,view)?
state: 驱动应用的数据源
view: 以声明方式将state 映射到视图
actions: 响应在view 上的用户输入导致的状态变化(包含n 个更新状态的方法)
# Vue router 跳转和 location.href 有什么区别?
router 是 hash 改变
location.href 是页面跳转,刷新页面
# 对MVVM的理解
MVVM由Model、View、ViewModel三部分构成
Model代表数据模型,也可以在Model中定义数据修改和业务逻辑;
View代表U组件,它负责将数据模型转化成UI展现出来;
ViewModel是一个同步View和Model的对象;
# position定位?
static HTML 元素的默认值,即没有定位,遵循正常的文档流对象。
relative 相对定位元素的定位是相对其正常位置。
fixed 元素的位置相对于浏览器窗口是固定位置
absolute 绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于<html>:
sticky 粘性定位。
# position和float的区别?
position 是定位,而float是浮动
# 浏览器缓存机制
浏览器缓存分为强缓存和协商缓存。缓存的作用是提高客户端速度、节省网络流量、降低服务器压力。
强缓存:浏览器请求资源,如果header中的Cache-Control和Expires没有过期,直接从缓存(本地)读取资源,不需要再向服务器请求资源。
协商缓存:浏览器请求的资源如果是过期的,那么会向服务器发送请求,header中带有Etag字段。服务器再进行判断,如果ETag匹配,则返回给客户端300系列状态码,客户端继续使用本地缓存;否则,客户端会重新获取数据资源。
# 如何理解html语义化
(1)去掉或丢失样式的时候能够让页面呈现出清晰的结构。
(2)有利于SEO和搜索引擎建立良好沟通,有助于爬虫抓取更多的信息,爬虫依赖于标签来确定上下文和各个关键字的权重。
(3)方便其它设备解析。
(4)便于团队开发和维护,语义化根据可读性。
# 页面导入样式时,使用link和@import有什么区别?
(1)link属于XHTML标签,除了加载css外,还能用于定义RSS(简易信息聚合,是一种基于XML标准),rel连接属性等作用;@import是css提供,只能用于加载css
(2)页面被加载时,link会同时被加载;@import引用的css会等到页面被加载完成后再加载
(3)link是XHTML标签,没有兼容问题;@import只有在IE5以上才能被识别
(4)link支持使用js控制dom修改样式;@import不支持
# promise和Async/await的优缺点
async/await优点:
a. 它做到了真正的串行的同步写法,代码阅读相对容易
b. 对于条件语句和其他流程语句比较友好,可以直接写到判断条件里面
c. 处理复杂流程时,在代码清晰度方面有优势
async/await缺点:
a. 无法处理promise返回的reject对象,要借助try…catch…
b. 用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。
c. try…catch…内部的变量无法传递给下一个try…catch…,Promise和then/catch内部定义的变量,能通过then链条的参数传递到下一个then/catch,但是async/await的try内部的变量,如果用let和const定义则无法传递到下一个try…catch…,只能在外层作用域先定义好。
promise的一些问题:
a. 一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来
b. 错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
c. Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
# 概述this及其作用
概述
(1)this是每次调用函数的时候都会向函数内部传递进一个隐含的参数。
(2)this指向的是一个对象,函数执行的上下文对象。
(3)根据函数的调用方式,this的指向也不同。
(4)我们可以把this理解为这个函数执行者。
注意:ES6中的箭头函数没有this指向的,它里面的 this 是继承外面的环境。
作用
(1)调用本类中的方法。
(2)表示类中的属性。
(3)可以使用this调用本类的构造方法。
(4)this表示当前对象。
# this指向问题
(1)普通函数调用,this指向全局对象-window
(2)对象函数调用,this指的是方法的调用者,就是那个实例对象
(3)事件函数调用,函数中的this指的是事件源
(4)定时函数调用,函数中的this指的是window
(5)实例对象的方法调用,函数中的this指的是方法的调用者,就是那个实例对象
# flex弹性布局怎么实现,有什么属性
flex是弹性布局,通过主轴和交叉轴俩条轴上的排布方式来控制布局
flex-direction属性决定主轴的方向(即项目的排列方向)。
flex-wrap属性: 默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
justify-content属性定义了项目在主轴上的对齐方式。
align-items属性定义项目在交叉轴上如何对齐。
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
# Javascript的事件流模型都有什么?
“事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个 阶段:事件捕捉,目标阶段,事件冒泡
# javascript中的垃圾回收机制?
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。
如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
因为函数a被b引用b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
# 首屏性能优化(具体场景:淘宝详情页的性能优化)
资源加载优化:
减少资源大小(代码压缩、图片压缩、代码拆分)
减少http请求次数(http强缓存、本地缓存)
提高http响应请求速度
优化资源加载时间(按需加载、懒加载、预加载)
优化资源、内容加载方式
页面渲染优化:
优化html代码(js外链放在底部、css外链放在顶部、减少DOM数量)
优化js、css代码(使用webworker、降低css选择器复杂性)
优化动画效果(使用transform和opacity属性来实现动画)
# 伪类和伪元素的区别
伪类和伪元素都是用来表示文档树以外的"元素"
伪类和伪元素分别用单冒号:和双冒号::来表示
伪类和伪元素的区别,最关键的点在于如果没有伪元素(或伪类),是否需要添加元素才能达到目的,如果是则是伪元素,反之则是伪类
# 图片的data:url和直接加在图片的优缺点?
图片被转换成base64编码的字符串形式,并存储在URL中。使用Data URL技术,图片数据以base64字符串格式嵌入到了页面中,与HTML成为一体。
当图片的体积太小,占用一个HTTP会话不是很值得时。可以使用Data url
Data URL形式的图片不会被浏览器缓存,这意味着每次访问这样页面时都被下载一次。这是一个使用效率方面的问题——尤其当这个图片被整个网站大量使用的时候。不适用。
可以将Data URL形式的图片存储在CSS样式表中。而所有浏览器都会积极的缓存CSS文件来提高页面加载效率。
只要这个图片不是很大,而且不是在CSS文件里反复使用,就可以以Data URL方法呈现图片降低页面的加载时间,改善用户的浏览体验。
# 如何理解前端模块化
前端模块化就是复杂的文件编程一个一个独立的模块,比如 JS 文件等等,分成独立的
模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,
所以有了 commonJS 规范,AMD,CMD 规范等等,以及用于 JS 打包(编译等处理)的
工具 webpack
# 数组去重
法一:indexOf 循环去重
法二:ES6 Set 去重;Array.from(new Set(array))
法三:Object 键值对去重;把数组的值存成 Object 的 key 值,比如 Object[value1] = true,
在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。
# 如何判断一个数组
Object.prototype.call.toString()
instanceof
# 你说到typeof,能不能加一个限制条件达到判断条件
typeof 只能判断是 object,可以判断一下是否拥有数组的方法
# node 怎么接收请求和处理的
# Node.js的优势,用过Node.js哪些模块
# 用node实现多进程
# 箭头函数,箭头函数和普通函数的区别(语法和this指向)
箭头函数根本就没有绑定自己的 this,在箭头函数中调用 this 时,仅仅是简单的沿着作
用域链向上寻找,找到最近的一个 this 拿来使用
# 为什么timer声明的时候没有初始化为0或者null(undefined会在if时类型转化成false,然后解释了可以转化成false的各种情况)
# 前端怎么发起请求的,有哪些方式
# promise全链路捕获异常
# promise和async的区别
# ejs的原理及实现
# 什么样的const值可以更改,什么样的不能
# CORS原理是什么?
CORS 是跨域资源共享的缩写,是一种新标准,支持同源通信,也支持跨域通信。fetch是实现CORS通信的
该技术通过在目标域名返回 CORS 响应头来达到获取该域名的数据的目的
该技术核心就是设置 response header,分为简单请求和复杂请求两种
简单请求只需要设置 Access-Control-Allow-Origin: 目标源 即可,复杂请求则分两步走,第一步是浏览器发起 OPTIONS 请求,第二步才是真实请求。OPTIONS 请求需要把服务器支持的操作通过响应头来表明,如 Access-Control-Allow-Methods: POST, GET, OPTIONS,另外一个重要的响应头是 Access-Control-Allow-Credentials: true 用来表明是否接受请求中的 Cookie。
优点是通过简单的配置就能跨域
缺点是某些古老浏览器不支持 CORS 或不支持 Credentials
解决办法是用 JSONP 或 P3P 等技术
# 画一条0.5px的直线?
height: 1px;
transform: scale(0.5);
# Ajax原理
(1)创建对象
var xhr = new XMLHttpRequest();
(2)打开请求
xhr.open('GET', 'example.txt', true);
(3)发送请求
xhr.send(); 发送请求到服务器
(4)接收响应
xhr.onreadystatechange =function(){}
(1)当readystate值从一个值变为另一个值时,都会触发readystatechange事件。
(2)当readystate==4时,表示已经接收到全部响应数据。
(3)当status ==200时,表示服务器成功返回页面和数据。
(4)如果(2)和(3)内容同时满足,则可以通过xhr.responseText,获得服务器返回的内容。
# 场景题:提交表单,常用的方法有哪些?应用层,通信层发生了哪些过程?
提交表单方法
最常用的方式是get和post
通过form配置action和method实现
通过ajax实现
应用层、通信层发生了哪些过程?
浏览器发送请求后,通过DNS解析域名查找IP地址
经过应用层HTTP
通信层(TCP/IP)生成http报文及请求,经过三次握手和四次挥手,解析请求报文并生成响应报文
# post和get的区别,列举一下
GET主要拉取数据,POST主要提交保存数据;
GET传输一般2kb,POST没有大小限制;
GET请求浏览器会记录,可以缓存,POST不会;
GET通过url编码,POST支持多种编码
GET比POST更不安全,因为参数暴露在URL中,POST不会。
# http常见的响应码,拒绝服务资源是哪个(403)
200 请求成功
202(Accepted),服务器已接受请求,但尚未处理。
204(No-Content),服务器成功处理了请求,但不需要返回任何实体内容
205(Reset-Content),服务器成功处理了请求,且没有返回任何内容。
206(Partial-Content),服务器已经成功处理了部分 GET 请求。
301 永久重定向,一般是地址发生变化
302 临时重定向
304 Not Modified(通常是在协商缓存中表示本次内容未修改)
如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,
则服务器应当返回这个状态码。即客户端和服务器端只需要传输很少的数据量来做文件的校验,如果文件没有修改过,则不需要返回全量的数据
400 Bad Request - 前端请求错误
401 Unauthorized - 未授权
402 为以后需要所保留的状态码。
403 Forbidden - 请求被拒绝(本题答案)
404 Not Found - 资源不存在
500 Inter Server Error - 服务端异常
502 Bad Gateway 网关出错
503 Server Unavailable - 服务不可用
# 说一说这个系统是如何判断机制的(前端鉴权)
鉴权主要分为四种:
HTTP基本认证(HTTP Basic Authentication)
session-cookie
Token验证(包括JWT,SSO)
OAuth(开放授权)
# 你刚才说了三方OAuth,讲一讲内在原理吧
当用户点击按钮时页面跳转到第三方授权网站
在用户选择同意授权后,重定向回来并携带一个code,这个code是微信下发的临时凭证
开发者根据code获取微信access_token
然后拿到token就有权限借此通过相应的接口拉取用户资料
# 说说https的内在原理,ssl握手过程
https实际上是在应用层(http)和传输层(tcp)之间加了一层安全套接层(ssl).
https原理
客户端发送Https请求
服务端收到请求并配置CA证书(包含公钥和私钥)
服务端发送证书给客户端(包含颁发机构、过期时间)
客户端拿到证书并进行解析(由TLS验证证书有效性)
验证无误后,生成随机数并加密,传回给服务端
服务端解密随机值,把响应内容通过私钥进行对称加密,传输给客户端
客户端通过证书解密,获取服务端响应内容
ssl握手过程
客户端给服务器端发送:协议版本、客户端支持的加密算法、一个随机数1。
服务器端选择加密算法,并向客户端发送一个数字证书和一个随机数2。
客户端使用数字证书中的公钥,将随机数3加密发送给服务器。
服务器使用私钥对随机数字3解密,用加密方法计算生成对称加密的密钥给客户端
服务器端和客户端通过事先协商好的加密算法,对这三个随机数进行加密生成“对话秘钥”(session key)即对称加密的秘钥,用于接下来整个对话过程的加密。
# 为什么要用非对称密钥,pms呢?公钥怎么了?
非对称加密相对更安全,通过公钥解密后,只有私钥才能解密,而对称加密只需要一个密钥就能加密和解密。
PMS(pre master secret),SSL协议并不信任每个主机生成的随机数,因此PMS也有可能被推测出来,所以需要客户端、服务端和PMS三个随机数一同生成密钥才更安全。
# 说一说响应式布局吧?
响应式布局是指同一个网站在不同屏幕尺寸下显示不同的布局。
它跟自适应不同,自适应是同一个网站在不同设备上自适应(比如自适应不同的Android和iPhone设备)。传统的做法会针对PC、移动端各做一套项目,而响应式会同时支持PC和H5。
响应式方案:
1.通过rem进行百分比布局,根据html的根元素来决定元素大小的。
2.Bootstrap/ElementUI中的栅格布局,本身也是一种响应式。
3.Flex-box 软盒子模式布局。
4.视窗(vw/vh),c3中新增视窗,1vw代表1%的宽度,通常结合rem一起使用。
# 响应式背后的浏览器原理你知道吗?(不太知道)
根据浏览器或设备的分辨率可以计算获取到相应的尺寸,通过不同的尺寸可以动态的修改html元素或者盒子在浏览器中的大小,从而实现响应式。
# 旋转动画css,怎么去做?(animation+rotate)
transition+transform
transition:all 1s linear;
transform:rotate(360deg);
animation
animation:rotate 5s infinite
@keyframes rotate
{
from{transform:rotate(0deg);}
to{transform:rotate(360deg);}
}
# 如何删除一个 cookie?
删除Cookie的唯一方法是: 将Expires设置为一个过去值, 一般会设置为 Thu, 01-Jan-1970 00:00:01 GMT 因为这是时间零点, 设这个总不会错.
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
# 为什么link要在前,script标签要在后面呢?原理
link标签并不只会阻塞DOM解析,会阻塞DOM渲染,而script加载js过程会阻塞DOM渲染和CSS加载,所以为了更好的用户体验和更优的前端性能,我们通常把link放前面,script放后面。
js之所以阻塞DOM渲染是因为JS本身是单线程,在执行的过程中只能从上到下依次运行,异步任务除外
# 场景题:保证浏览器不受脚本的恶意攻击,(xss攻击,解决方法)
主要考察前端漏洞:XSS攻击和CSRF攻击
XSS主要指跨站脚本攻击,一般会伪造网站,窃取cookie,也包括一些sql注入和html注入等;
防御方法:
后端对请求数据做标签过滤和检查。
服务端可设置cookie为httponly,这样前端无法读取,只有服务端可读取
/**CSRF主要指跨站请求伪造,其原理是通过向A中注入链接,使用户跳转到B中并获取A站的cookie,通过cookie向A发送请求,以达到攻击目的。
防御方法:
使用POST代替GET
设置cookie为httponly
增加token
通过Referer识别网站**/
# EventLoop理解
它的大概步骤是:
1.Js的事件分为同步任务和异步任务.
2.遇到同步任务就放在执行栈中执行.
3.遇到异步任务就放到任务队列之中,等到执行栈执行完毕之后再去执行任务队列之中的事件.
# 防抖和节流
相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减.避免大量计算导致的页面卡顿.
不同:防抖是将多次执行变为最后一次执行,节流是将多次执行变为在规定时间内只执行一次.
防抖是指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间。
主要运用在:输入搜索联想,用户在不断输入值时,用防抖来节约请求资源;按钮点击:收藏,点赞等
节流是指当持续触发事件时,在规定时间段内只能调用一次回调函数。如果在规定时间内又触发了该事件,则什么也不做,也不会重置定时器。
主要运用在:鼠标不断点击触发,点击事件在规定时间内只触发一次;监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
防抖:
function debounce(fn,wait=50) {
let timer;
return function(...args) {
if(timer) clearTimeout(timer)
timer = setTimeout(()=> {
fn.apply(this,args)
},wait)
}
}
# 对象深度克隆(深拷贝)的简单实现
function deepClone(obj){
var newObj= obj instanceof Array ? []:{};
for(var item in obj){
var temple= typeof obj[item] == 'object' ? deepClone(obj[item]):obj[item];
newObj[item] = temple;
}
return newObj;
}
# 自己实现一个bind函数
原理:通过 apply 或者 call 方法来实现。
Function.prototype.bind=function(obj,arg){
var arg=Array.prototype.slice.call(arguments,1);
var context=this;
return function(newArg){
arg=arg.concat(Array.prototype.slice.call(newArg));
return context.apply(obj,arg);
}
}
# 重构、回流
浏览器的重构指的是改变每个元素外观时所触发的浏览器行为,比如颜色,背景等样式发生了改变而进行的重新构造新外观的过程。重构不会引发页面的重新布局,不一定伴随着回流;
回流指的是浏览器为了重新渲染页面的需要而进行的重新计算元素的几何大小和位置的,他的开销是非常大的,回流可以理解为渲染树需要重新进行计算,一般最好触发元素的重构,避免元素的回流;
比如通过通过添加类来添加css样式,而不是直接在DOM上设置,当需要操作某一块元素时候,最好使其脱离文档流,这样就不会引起回流了,比如设置position:absolute或者fixed,或者display:none,等操作结束后在显示。
# 在地址栏里输入一个 URL后,按下 Enter 到这个页面呈现出来,中间会发生什么?
检查缓存
DNS解析
TCP连接
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束
# 简述页面渲染的过程
解析HTML生成DOM树
解析CSS生成CSSOM规则树
将DOM树与CSSOM规则树合并在一起生成渲染树
遍历渲染树开始布局,计算每个节点的位置大小信息
将渲染树每个节点绘制到屏幕
# dom树和cssom树原理也说一下吧
# 假如说你的富文本编辑器内部要显示脚本,该怎么办呢?(不太清楚,我就尽可能说)
# 场景题:promise.resolve.then和setTimeout(有关事件循环event loop)
# 说说async和await的es5实现(我尽可能地说了一点)
# 场景题:这里有cat和animal子类和父类,如何进行es5继承,至少说出5种。
原型链继承
借用构造函数继承
组合继承(原型+构造)
Call/Apply继承
寄生式继承
寄生组合继承
# 浅拷贝和深拷贝的问题
1. 深拷贝和浅拷贝是只针对Object和Array这样的复杂类型的
2. 也就是说a和b指向了同一块内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
3. 浅拷贝, ”Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
4. 深拷贝,JSON.parse()和JSON.stringify()给了我们一个基本的解决办法。但是函数不能被正确处理
# 前端优化(提高网页的加载速度)
1、使用css sprites,可以有效的减少http请求数
2、使用缓存
3、压缩js,css文件,减小文件体积
4、使用cdn,减小服务器负担
5、懒加载图片
6、预加载css,js文件
7、避免dom结构的深层次嵌套
8、给DOM元素添加样式时,把样式放到类中,直接给元素添加类,减少重构,回流
# 说说webpack打包构建在实际项目中的优化
JS代码压缩
CSS代码压缩
Html文件代码压缩
文件大小压缩
图片压缩
Tree Shaking
webpack实现Trss shaking有两种不同的方案:
usedExports:通过标记某些函数是否被使用,之后通过Terser来进行优化的
sideEffects:跳过整个模块/文件,直接查看该文件是否有副作用
代码分离
内联 chunk
# new 操作符具体干了什么?
首先是创建实例对象{}
this 变量引用该对象,同时还继承了构造函数的原型
其次属性和方法被加入到 this 引用的对象中
并且新创建的对象由 this 所引用,最后隐式的返回 this