前端JS面试题总结
你是如何理解原型 和原型链得?
- 把所有对象共用得属性放在一个堆内存对象上(共用属性组成得对象),然后让每一个对象得_propto_ 存储这个【共用属性组成得对象】得地址,而这个公用属性就是原型
- 原型得出现就是为了减少不必要得内存消耗,而原型链就是对象通过__proto__向当前实例所属类得原型上查找属性或方法得hi之,如果找到 Object 得原型上还是没有找到想要得属性或者方法则查找结束,最终会返回undefined
从输入url地址到页面相应都发生了什么?
- 浏览器查找当前 URL 是否缓存,在比对国企时间
- DNS 解析URL 对应得 IP
- 根据 IP 建立 TCP 连接(三次握手)
- HTTP发起请求。
- 服务器处理请求,浏览器接收HTTP响应。
- 渲染页面,构建DOM 树
- 关闭 TCP连接(四次挥手)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zd6IVbKo-1572240544629)(d:\image\1572176051214.png)]
session、cookie、localStorage的区别
相同点
- 都是保存在浏览器端,而且是同源的
不同点
-
cookie 数据始终在同源得http 请求中携带,即cookie 在浏览器 和服务器中 来回传递
-
而 sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存
-
cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据。
-
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;
-
localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
-
cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
-
localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
JS中得跨域问题(同源策略=》协议 端口 域名都要相同)
-
Jsonp
-
原理: script 得 src 属性不受 同源策略得限制,因为所有得是src 和 href 都不受同源策略得限制,可以请求第三方得服务器资源
-
实现步骤
- 创建一个script 标签
- script 得src 属性设置接口地址
- 接口参数,必须要带一个自定义函数名(回调函数)
- 回调函数去接收返回得数据
-
-
document.domain 基础域名相同 子域名不同
-
window.name 利用在一个浏览器窗口内,载入所有的域名都是共享一个window.name
-
Cors 服务器设置对Cors 得支持
- 原理:服务器设置 Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求
-
利用h5新特性window.postMessage()
前端有哪些页面优化方法?
- 减少 HTTP请求数
- 从设计实现层面简化页面
- 合理设置 HTTP缓存
- 资源合并与压缩
- 合并 CSS图片,减少请求数的又一个好办法。
- 将外部脚本置底(将脚本内容在页面信息内容加载后再加载)
- 多图片网页使用图片懒加载。
- 在js中尽量减少闭包的使用
- 尽量合并css和js文件
- 尽量使用字体图标或者SVG图标,来代替传统的PNG等格式的图片
- 减少对DOM的操作
- 在JS中避免“嵌套循环”和 “死循环”
- 尽可能使用事件委托(事件代理)来处理事件绑定的操作
splice和slice、map和forEach、 filter()、reduce()的区别
- splice 可以删除 也可以新增 ,第三个参数有值,就代表着新增,会修改原数组
- splice(index,howmany,item1,…itemx)
- slice(start,end) 会返回一个新的数组
- map : 会返回一个全新得数组,使用于改变数据值得时候,会分配内存存储空间并返回
- forEach(),不会返回任何有价值得东西,并不打算改变数据
- redece 方法接收一个韩式作为累加器
- filter():创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aluicXbv-1572240544631)(d:\image\1572180290728.png)]
V- model 得原理是
-
Vue 得双向数据绑定是由数据劫持 以及 发布者订阅者实现得。在数据劫持是通过 Object.definProperty()来劫持对象数据得 setter 和 getter 操作
- 原理 通过Observer(监听器)来监听自己的model数据变化,通过Compile(指令解析器Compile)来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化->视图更新 在初始化vue实例时,遍历data这个对象,给每一个键值对利用Object.definedProperty对data的键值对新增get和set方法,利用了事件监听DOM的机制,让视图去改变数据
- Object.defineProperty( )是用来做什么的?它可以来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举,这里我们主要先来研究下它对应的两个描述属性get和set,
实现过程
- 1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
- 2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
- 3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
谈谈对生命周期的理解
- beforeCreate : 此时 vue 实例挂载得元素 el 和 数据对象 data 都是undefined,还没有没初始化
- create : 此时已经有了 data 但是现在 el 可以访问里面得数据和方法了
- beforeMount : vue 得实例 el 和 data 都初始化了吗,但是挂载之前威虚拟得dom 节点
- mounted : vue 实例挂载到真实DOM 上,就可以通过DOM 获取DOM节点
- beforeUpdate : 在响应式数据更新之前调用,适合在更新之前访问现有得DOM ,比如手动移除已经添加得事件监听器 removeEventListener()
- updated: DOM 已经更新,避免在这个阶段操作数据,否则导致死循环
- beforedestroy:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件
- destrory : 实例销毁后调用,调用后所有事件监听器会被移除,所有得子实力都会被销毁
Vue 和 React 有什么区别
- React 整体是函数式编程思想
- 单向数据流
- 状态和逻辑通过参数传入
- 把组件设计成纯组件
- Vue 是响应式思想
- 基于数据可变的
- 通过对每一个属性建立Watcher来监听
- 当属性变化的时候,响应式的更新对应的虚拟dom
Vuex的流程
- 页面通过 mapState 异步操作 到 Action
- Action 通过 同步操作 commit 到 mutation
- mutation 修改 state ,最后 通过 getter 把对应值跑出去
- 在页面的计算属性中通过mapGetter来动态获取state中的值
- modules:模块化vuex
Vue路由的俩种模式
- hash
- 即地址栏URL 中的 # 符号,改变hash 不会重新加载页面
- history
- 利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法
$route
和$router
的区别
$route
是 路由信息对象,包括path,param,hash,query,fullPath,marched,name 等路由信息参数$router
是 路由实例,对象包括了路由的跳转方法,钩子函数
axios是什么?怎么使用?描述使用它实现登录功能的流程?
- 请求后台资源的模块
- 然后发送的是跨域,需在配置文件中config/index.js进行设置。后台如果是Tp5则定义一个资源路由。 js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中
vue修饰符
- stop:阻止事件的冒泡
- prevent:阻止事件的默认行为
- once:只触发一次
- self:只触发自己的事件行为时,才会执行
vue项目中的性能优化
1.不要在模板里面写过多表达式
2.循环调用子组件时添加key
3.频繁切换的使用v-show,不频繁切换的使用v-if
4.尽量少用float,可以用flex
5.按需加载,可以用require或者import()按需加载需要的组件
6.路由懒加载
react和vue的区别
-
=> 相同点: 1.数据驱动页面,提供响应式的试图组件 2.都有virtual DOM,组件化的开发,通过props参数进行父子之间组件传递数据,都实现了webComponents规范 3.数据流动单向,都支持服务器的渲染SSR 4.都有支持native的方法,react有React native, vue有wexx
-
=> 不同点: 1.数据绑定:Vue实现了双向的数据绑定,react数据流动是单向的 2.数据渲染:大规模的数据渲染,react更快 3.使用场景:React配合Redux架构适合大规模多人协作复杂项目,Vue适合小快的项目 4.开发风格:react推荐做法jsx + inline style把html和css都写在js了 vue是采用webpack + vue-loader单文件组件格式,html, js, css同一个文件
常见的web安全及防护原理
-
sql注入原理:通过sql命令插入到web表单递交或者输入活命,达到欺骗服务器执行的恶意sql命令
- 防范:1.对用户输入进行校验
- 2.不适用动态拼接sql
-
XSS(跨站脚本攻击):往web页面插入恶意的html标签或者js代码。
- 举例子:在论坛放置一个看是安全的链接,窃取cookie中的用户信息
- 防范:尽量采用post而不使用get提交表单
- 避免cookie中泄漏用户的隐式
-
CSRF(跨站请求伪装):通过伪装来自受信任用户的请求
- 举例子:黄轶老师的webapp音乐请求数据就是利用CSRF跨站请求伪装来获取QQ音乐的数据
- 防范:在客服端页面增加伪随机数,通过验证码
-
XSS和CSRF的区别:
- XSS是获取信息,不需要提前知道其他用户页面的代码和数据包
- CSRF代替用户完成指定的动作,需要知道其他页面的代码和数据包
观察者模式 vs 发布-订阅模式
- 发布 + 订阅 = 观察者模式
观察者模式 在软件设计中是一个对象,维护一个依赖列表,当任何状态发生改变自动通知它们。
在发布-订阅模式,消息的发送方,叫做发布者(publishers),消息不会直接发送给特定的接收者,叫做订阅者。
- 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
- 在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
- 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
- 观察者 模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。
尽管它们之间有区别,但有些人可能会说发布-订阅模式是观察者模式的变异,因为它们概念上是相似的。
数组去重
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
let res = [],
obj = {}
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
res.push(arr[i])
obj[arr[i]] = 1
} else {
obj[arr[i]]++
}
}
return res
}
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
return [...new Set(arr)]
}