5道偏原理的面试题

写在前面

CSDN话题挑战赛第1期

  • 活动详情地址:https://marketing.csdn.net/p/bb5081d88a77db8d6ef45bb7b6ef3d7f
  • 参赛话题:前端面试宝典
  • 话题描述:欢迎各位加入话题创作得小伙伴,如果我没有猜错得话,我觉得你是应该同我一样是一位前端人。如今前端在IT事业中的占比越来越重,已经成为不可缺少的部分,前端技术也是层出不穷,各种技术类、技术框架也蜂拥而出,前端面试的难度也随之增加,如果我们拥有一套前端面试宝典。如果你是应聘者:你就可以从容的solo面试官,如果你是面试官:你就可以将应聘者拷问到骨子里!
    总之我们大家一起将自己的面试经验以及学习到的知识点汇聚于此,形成一套体系的前端面试宝典。让读者无论是面试还是学习都能够有非常大的收获。就让我们携手共筑前端面试宝典吧!!!

Vue面试题汇总

简单的聊聊new Vue以后发生的事

答案

  1. new Vue会调用Vue原型链上的_init方法对Vue实例进行初始化
  2. 首先initLifecycle初始化声明周期,对Vue实例的内部的一些属性(如childrenparentisMount)进行初始化
  3. initEvents,初始化当前实例上的一些自定义事件(Vue.$on
  4. initRender,解析slots绑定在Vue实例上,绑定createElement方法实例上
  5. 完成对生命周期、自定义事件等一系列属性的初始化后,触发生命周期钩子beforeCreate
  6. initInjections,在初始化dataprops之前完成依赖注入(类似于React.Content
  7. initState,完成对dataprops的初始化,同时对属性完成数据劫持内部,启用监听者对数据进行监听(更改)
  8. initProvide,对依赖注入进行解析
  9. 完成对数据(state状态)的初始化后,触发生命周期钩子created
  10. 进入挂载阶段,将Vue模板语法通过vue-loader解析成虚拟DOM树,虚拟DOM树与数据完成双向绑定,触发生命周期钩子beforeMount
  11. 将解析好的虚拟DOM树通过vue渲染成真实的DOM,触发生命周期钩子mounted

vue中,HashRouter和HistoryRouter的区别和原理

答案

vue-router是 Vue官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。vue-router默认hash模式,还有一种是history模式。

拓展

  1. hash路由: hash模式的工作原理是hashchange事件,可以在window监听hash的变化。我们在url后面随便添加一个#xx触发这个事件。vue-router默认的是hash模式—使用URLhash来模拟一个完整的URL,于是当URL改变的时候,页面不会重新加载,也就是单页应用了,当#后面的hash发生变化,不会导致浏览器向服务器发出请求,浏览器不发出请求就不会刷新页面,并且会触发hasChange这个事件,通过监听hash值的变化来实现更新页面部分内容的操作
    对于hash模式会创建hashHistory对象,在访问不同的路由的时候,会发生两件事:
    1. HashHistory.push()将新的路由添加到浏览器访问的历史的栈顶,
    2. HasHistory.replace()替换到当前栈顶的路由
  2. history路由
    主要使用HTML5pushState()replaceState()这两个api结合window.popstate事件(监听浏览器前进后退)来实现的,pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改
  3. 区别
    1. hash模式较丑,history模式较优雅
    2. pushState设置的新URL可以是与当前URL同源的任意URL;而hash只可修改#后面的部分,故只可设置与当前同文档的URL
    3. pushState设置的新URL可以与当前URL一模一样,这样也会把记录添加到栈中;而hash设置的新值必须与原来不一样才会触发记录添加到栈中
    4. pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串
    5. pushstate可额外设置title属性供后续使用
    6. hash兼容IE8以上,history兼容IE10以上
    7. history模式需要后端配合将所有访问都指向index.html,否则用户刷新页面,会导致404错误

mutation和action有什么区别?

答案

  • mutation
    更改Vuexstore 中的状态的唯一方法是提交 mutationVuex中的 mutation非常类似于件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state 作为第一个参数
const  store  =  new  Vuex.Store({  
   state:  {    
   count:  1  
 },
mutations:  {    
increment (state)  {
 // 变更状态 
state.count++
		} 
 	}
 }) 

不能直接调用一个mutation handler。这个选项更像是事件注册:“当触发一个类型为incrementmutation 时,调用此函数。"要唤醒一个mutationhandler,你需要以相应的type调用store.commit方法:

store.commit('increment') 
  • Action
    Action类似于mutation,不同在于:Action提交的是mutation,而不是直接变更状态。
    Action可以包含任意异步操作。
    注册一个简单的action:
const  store  =  new  Vuex.Store({  
    state:  {    
        count:  0  
    },
      mutations:  {    
        increment (state)  {      
            state.count++    
        }  
    },
      actions:  {    
        increment (context)  {      
            context.commit('increment')    
        }  
    }
}) 

拓展

vuex真正限制你的只有mutation必须是同步的这一点(在redux里面就好像reducer必须同步返回下一个状态一样)。
同步的意义在于这样每一个mutation 执行完成后都可以对应到一个新的状态(和reducer 一样),这样devtools就可以打个snapshot存下来,然后就可以随便time-travel 了。如果你开着devtool调用一个异步的action,你可以清楚地看到它所调用的 mutation是何时被记录下来的,并且可以立刻查看它们对应的状态。

使用方法

// hash路由原理      
// 监听hashchange方法
window.addEventListener('hashchange',()=>{
	div.innerHTML = location.hash.slice(1)
})
// history路由原理
// 利用html5的history的pushState方法结合window.popstate事件(监听浏览器前进后退)        function routerChange (pathname){            history.pushState(null,null,pathname)            div.innerHTML = location.pathname
} 
window.addEventListener('popstate',()=> { 
    div.innerHTML = location.pathname
})

聊聊Vue2双向绑定的缺陷

答案

  1. vue 实例创建后,无法检测到对象属性的新增删除,只能追踪到数据是否被修改
  2. 不能监听数组的变化

拓展

解决方案:

  • 使用$set给侦听属性

*对数组使用其数组方法 push/pop/shift/unshift/splice/sort/reverse

重写数组方法的原理

const  methods = ['pop', 'shift', 'unshift', 'sort', 'reverse', 'splice',  'push']; 

// 复制Array.prototype,并将其prototype指向
Array.prototypelet proto = Object.create(Array.prototype);methods.forEach(met
hod => {   
proto[method] = function () { 
// 重写proto中的数组方法        
Array.prototype[method].call(this, ...arguments);        
viewRender() 
// 视图更新       
function observe(obj) { 
	if (Array.isArray(obj)) {
// 数组实现响应式
 obj.__proto__ = proto; // 改变传入数组的prototype  
return; 
}
            
if (typeof obj === 'object') {  
              ... // 对象的响应式实现
 		} 
 	} 
  }})

delete和Vue.delete删除数组的区别

答案

delete只是被删除的元素变成了empty/undefined其他的元素的键值还是不变。
vue.delete直接删除了数组改变了数组的键值

var  a = [1, 2, 3, 4]
var  b = [1, 2, 3, 4] 
delete  a[0] 
console.log(a)  
//[empty,2,3,4]
this.$delete(b,0)
console.log(b)  //[2,3,4]

写在最后

CSDN话题挑战赛第1期

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值