箭头函数this指向
- 默认指向定义它时所处的上下文的对象的this指向,没有上下文就指向window
- 即使是call apply bind等方法也不能改变箭头函数this的指向
说说this指向
普通函数中:
- 总是指向它的直接调用者
- 没有直接调用者指向window
- 使用call apply bind绑定,this指向绑定的对象
箭头函数中同上
vuex原理
不会啊
created和mounted区别
created:在模板渲染成html 前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html 后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
nextTick原理
使用场景:
+ 在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到 DOM。
原因:
这里就涉及到 Vue 一个很重要的概念:异步更新队列(JS运行机制 、 事件循环)。
Vue 在观察到数据变化时并不是直接更新 DOM,而是开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。
在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。
然后,在下一个事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。
所以如果用 for 循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,是一个很大的开销,损耗性能。
nextTick 就是设置一个回调,用于异步执行
异步执行,比如,就是把你设置的回调放在 setTimeout 中执行,这样就算异步了,等待当时同步代码执行完毕再执行
但是,每设置一个 nextTick 就新建一个 setTimeout 又不实际,
毕竟一个 setTimeout 是异步,两个setTimeout 也是异步,两个都要等在 同步代码执行完毕之后才执行
那直接只设置一个 setTimeout 不就好了
那一个 setTimeout 怎么执行多个回调呢?
-
存在 回调数组 里。每次调用 nextTick,便往数组里面 push 设置的回调
-
只注册一个 setTimeout,时间为0,用于遍历 回调数组,然后逐个执行子项
-
同步代码执行完毕,setTimeout 自然会执行
响应式原理
MVVM(框架)
M - Model 模型(数据)
V - View 视图(DOM)
VM - 视图模型(虚拟DOM)即vue实例中的声明式变量
DOM操作最耗费性能的一种
现在的数据都是动态渲染的,没有静态的,动态渲染就是DOM操作的一个过程,DOM操作又是最耗费性能的操作,MVVM就应运而生。
data中声明式的变量,双向绑定(响应式)
Vue构建的这样一个系统,就叫做响应式系统.
放在Data里的数据都有响应式功能
- 虚拟DOM是在挂载时创建(beforemount mounted);创建后存放在内存里,形式是一个json文件,一个基于真实DOM的文件描述。
beforemounted和mounted里创建json文件,形成虚拟dom,我们称此为VM,页面不刷新,则此json文件一直存在内存里, - 当vue里任何声明式变量发生变化时,vue会复制一份新的VM,将两者进行Diff运算-----------------------------Diff运算发生在BeforeUpdate 和 Updated之间
var dirty = Diff(vm1,vm2); - 遍历两个虚拟dom,找出最小差异,值存储在dirty里的值,通知vue去更新dom。
和Jquery相比,Vue极大减少了DOM操作.
vue3双向绑定改进
移动端怎么适配
强缓存和协商缓存什么情况下触发,通过哪个字段?
浏览器缓存(Brower Caching)是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省宽带,提高访问速度,降低服务器压力。
强缓存
强缓存离不开两个响应头 Expires 与 Cache-Control
- Expires:Expires是http1.0提出的⼀个表示资源过期时间的header,它描述的是⼀个绝对时间,由服务器返回,Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效
- Cache-Control: Cache-Control 出现于 HTTP / 1.1,优先级⾼于 Expires ,表示的是相对时间
- 主流的做法使⽤ Cache-Control 控制缓存,除了 max-age 控制过期时间外,还有⼀些不得不提 - Cache-Control: public可以被所有⽤户缓存,包括终端和CDN等中间代理服务器 - Cache-Control: private只能被终端浏览器缓存,不允许中继缓存服务器进⾏缓存 - Cache-Control: no-cache,先缓存本地,但是在命中缓存之后必须与服务器验证缓存的新鲜度才能使⽤ - Cache-Control: no-store,不会产⽣任何缓存
协商缓存
当第⼀次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期或它的属性设置为no-cache时,那么浏览器第⼆次请求时就会与服务器进⾏协商。
如果缓存和服务端资源的最新版本是⼀致的,那么就⽆需再次下载该资源,服务端直接返回304 Not Modified 状态码,如果服务器发现浏览器中的缓存已经是旧版本了,那么服务器就会把最新资源的完整内容返回给浏览器,状态码就是200 Ok。
服务器判断缓存是否是新鲜的⽅法就是依靠HTTP的另外两组信息
Last-Modified/If-Modified-Since
客户端⾸次请求资源时,服务器会把资源的最新修改时间 Last-Modified:Thu, 19 Feb 2019 08:20:55 GMT 通过响应部⾸发送给客户端,当再次发送请求是,客户端将服务器返回的修改时间放在请求头 If-Modified-Since:Thu, 19 Feb 201908:20:55 GMT 发送给服务器,服务器再跟服务器上的对应资源进⾏⽐对,如果服务器的资源更新,那么返回最新的资源,此时状态码200,当服务器资源跟客户端的请求的部⾸时间⼀致,证明客户端的资源是最新的,返回304状态码,表示客户端直接⽤缓存即可。
ETag/If-None-Match
ETag的流程跟Last-Modified是类似的,区别就在于ETag是根据资源内容进⾏hash,⽣成⼀个信息摘要,只要资源内容有变化,这个摘要就会发⽣巨变,通过这个摘要信息⽐对,即可确定客户端的缓存资源是否为最新,这⽐Last-Modified的精确度要更⾼。
ES6新特性
- let 和 const,与var不同,let和const都是用于命名局部变量,都是块级作用域。
- 模版字符串
- 箭头函数:不需要用关键字function来定义函数;一般情况下可以省略return;在箭头函数内部,this并不会跟其他函数一样指向调用它的对象,而是继承上下文的this指向的对象。
- 函数可以设置默认参数值
- Spread / Rest 操作符
- 对象和数组解构
- 允许在对象中使用super方法
- 迭代器iterator、for…of和for…in
- class
web攻击,除了xss还有什么,什么情况下触发xss,除了脚本注入还有什么,如何避免
xss跨站脚本攻击(Cross Site Scripting)
- 如果网站带有评论功能并将评论内容直接存到服务器中,那么显示评论的时候就可能遭到之前恶意用户恶意评论的攻击
- 原理主要是通过在评论中输入html标签,如标签,就相当于往你的网页中嵌入了一段脚本
- 理论上,所有可输入的地方没有对输入数据进行处理的话,都会存在xss漏洞
防御方法
- 要坚持一个原则:永远不要相信用户的输入,对每一条输入都进行验证
- 可以用正则表达式验证输入内容的合法性
csrf跨站请求伪造(Cross-site Request Forgery)
攻击者盗用你的身份,发送恶意请求
要完成一次csrf攻击,被攻击者需要完成两个操作:
- 登录收信任网站A,并在本地生成cookie
- 在与A的会话结束前,访问危险网站B(危险网站B甚至可能是一个存在漏洞的受人信任的网站)
防御方法 - 在客户端表单增加伪随机数(但不能防止对方再利用xss攻击手段获得你的cookie)
- 在每次做类似提交表单的操作时都通过验证码进行验证
- 为每个表单设置不同的伪随机数(但会有并行会话兼容问题)
点击劫持(Click Jacking)
在我们浏览网页时经常会出现一些令人讨厌的信息,比如一些中奖通知或者色情信息,但在网页中散布这些内容却是不法分子用来诱惑被攻击者点击的常用手段,
点击劫持就是利用透明的iframe或者被覆盖的iframe,通过诱骗用户在该网页上点击某些按钮,触发iframe页面上的点击操作
防御方法
- 既然点击劫持的核心是iframe的嵌套,那么完全可以通过写一段javascript代码来禁止iframe的嵌套:
- X-FRAME-OPTIONS是目前最可靠的方法。
DENY // 拒绝任何域加载
SAMEORIGIN // 允许同源域下加载
ALLOW-FROM // 可以定义允许frame加载的页面地址
数据劫持:说说项目中哪些地方用到了数据劫持
数据劫持:
指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。
跨域,为什么会发送预检请求,什么情况下会发送预检请求
简单跨域请求。
当HTTP请求出现以下两种情况时,浏览器认为是简单跨域请求:
1). 请求方法是GET、HEAD或者POST,并且当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一个值。
2). 请求中没有自定义HTTP头部。
对于简单跨域请求,浏览器要做的就是在HTTP请求中添加Origin Header,将JavaScript脚本所在域填充进去,向其他域的服务器请求资源。服务器端收到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin Header。浏览器收到响应后,查看Access-Control-Allow-Origin Header,如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。
带预检(Preflighted)的跨域请求。
当HTTP请求出现以下两种情况时,浏览器认为是带预检(Preflighted)的跨域请求:
1). 除GET、HEAD和POST(only with application/x-www-form-urlencoded, multipart/form-data, text/plain Content-Type)以外的其他HTTP方法。
2). 请求中出现自定义HTTP头部。
Promise能中断吗,怎么中断
方法一:通过抛出一个异常来终止
方法二:通过reject来中断
说说时间循环机制
性能优化的方式
了解webpack吗
== 概念:== webpack大致分为四个:入口 出口 loader 插件是一个打包模块化js的工具,专注构建模块化项目
是一个模块打包器,强调模块化方案
打包原理
把所有的依赖打包成一个bundle.js然后通过代码分割单元片段并按需加载
打包流程:
- 识别入口文件
- 通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖-)
- webpack做的就是分析代码。转换代码,编译代码,输出代码
- 最终形成打包后的代码