前端面试题(持续更新...)
作者:互联网
HTML篇
cookie,localStorage,sessionStorage的区别
- 存储大小:cookie40kb左右,Storage20M左右
- 存储格式:cookie是字符串格式,Storage是键值对
- 通讯相关:cookie随请求携带,Storage不会自动携带
- 操作相关:cookie操作复杂,没有api前后端都可以操作;Storage操作简单,有api,只能前端操作。
- 时效相关:cookie默认是会话,可以手动设置;localStorage的存储是永久的,只有在手动删除或者卸载浏览器的时候才会被清除;sessionStorage是会话,当窗口或页面被关闭的时候会被清除
输入一个url到页面渲染发生了什么
- 浏览器地址栏输入URL并回车
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期
- DNS解析URL对应ip
- 根据ip建立TCP连接
- 发送http请求
- 服务器处理请求,浏览器接收HTTP响应
- 浏览器解析并渲染页面
- 关闭TCP连接
JS篇
JS的数据类型
基本数据类型:
- Number
- String
- boolean
- undefined
- null
- symbol
引用数据类型:
- Object 对象
- Array 数组
- function 函数
检测数据类型的方法
- typeof检测基本数据类型
-
A instanceof B 检测当前实例是否属于某各类
- Object.prototype.toString.call()
setTimeout和setInterval定时器无法按时执行的原因
js是单线程,所以异步事件仅在空闲时才会被调用,代码执行异步事件时会按照将它们添加到队列的顺序执行,如果队列是空的,那么添加代码会立即执行,如果队列不是空的,那么就要等前面代码执行完在执行。
ES6新特性
- 新增块级作用域let定义变量和const定义常量。
- 变量的结构赋值。
- 模板字符串。
- 箭头函数。
- 扩展运算符。
- 模块(import/export)
- 类(class/extends)
new操作符具体做了什么
- 在内存创建一个新对象
- 把构造函数中的this指向新建的对象
- 会在新对象上添加一个__proto__属性,指向函数的原型对象prototype
- 判断函数返回值,如果值是引用数据类型就直接返回值,否则就返回this(新建对象)
this指向的各种情况
- 全局作用域中的函数,在非严格模式下this的指向是window
- 对象内部函数,其内部this指向对象本身
- 构造函数:其内部this指向生成的实例对象
- apply,call,bind改变的this的指向,其this指向第一个参数
- 箭头函数没有自己的this,
闭包的理解
- 理解:主要是为了设计私有的方法和变量。
- 优点:可以避免全局变量造成的污染。
- 缺点:闭包会增加内存的使用量,使用不当会造成内存的泄露。
- 特征:函数是嵌套函数;在函数内部可以引用外部的参数和变量;参数和变量不会被垃圾回收机制回收。
call(),apply(),bind()的区别
- call()的参数是直接放进去的,第二个参数之后的参数全部都用逗号分隔
- apply()的所有参数都必须在一个数组传进去
- bind()除了返回的是函数以外,它的参数和call()一样
- 三者都可以改变this的指向对象
- 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null时,默认指向全局变量window
- 三者都可以传参,但是apply()是数组,而call()是参数列表,且apply()和call()是一次性传入参数,而bind()可以分为多次传入
- bind()是返回绑定this之后的函数,便于稍后调用;apply()和call()是立即执行
vue篇
什么是生命周期
vue实例有一个完整的生命周期,也就是从开始创建,初始化数据,编译模板,挂载DOM>渲染,更新>渲染,卸载等一系列过程称之为生命周期。
什么是指令
指令就是一套vue内置的模板,主要用于在视图节点上动态绑定变量,指令实际上也是DOM操作
自定义指令
在vue中,除了内置指令外,我们还可以使用vue.directive()或directives选项来自定义指令。
v-model的原理
在vue中v-model指令在表单input等元素上创建双向数据绑定,v-model本质上是一个语法糖,v-model在内部不同的元素使用不同的属性并抛出不同的事件
<input v-model="set" /> 相当于 <input v-bind:value="set" v-on:input="set"=$event.target.value />
vue响应式的原理
当vue组件被创建时,在生命周期的第一阶段(创建阶段)vue使用Object.defineProperty()对data选项进行遍历劫持并添加get/set钩子;在生命周期第二阶段(挂载阶段)指令与声明式变量touch时,会发生依赖收集,这时候再调用当前组件的watcher进行第一次Dom渲染,如果声明式变量发生变化时,vue会再次通知watcher更新视图。
理解vue的单向数据流
所有的props都使得其父子props之间形成了一个单向下行绑定:父级的更新会向下流动到子组件中,但是反过来不行,这样防止从子组件意外改变父组件的状态。
vue有哪些内置组件
插槽,动态组件,过渡动画,<component>
computed和watch的区别
computed是计算属性,依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下次获取的属性值才会重新计算。
watch更多的是观察的作用,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调
怎么理解组件化
组件化:把重复的代码提取出来封装成一个组件,实现组件的复用。
组件:组件就是HTML的一个扩展,使用粒度较小的HTML元素封装成组件
如何自定义组件
封装自定义组件的时候,可以使用vue选项属性,比如data,temolate,methods等
组件封装后,必须要组件注册才能在vue中使用,注册自定义组件时,组件名必须由多个单词用中划线连接
使用temolate选项指定组件的视图结构
如何进行组件注册
全局注册:使用Vue.component()进行全局注册,在任何组件中都可以使用
局部注册:使用components:{}进行局部注册,只有在当前组件作用域中使用。
注意:组件注册时,组件名称必须由多个单词用中划线连接
组件化的三大技术
自定义属性: <qf-score :num='num' count='1'></qf-score>
自定义事件: <qf-score @change='' @click=''></qf-score>
自定义插槽: <qf-score> <div #default></div> </qf-score>
组件的关系与通信
约定:在MVVM框架中,当我们谈论“组件”概念时,通常指的是自定义组件。当在A组件视图结构中使用到B组件,就会形成组件关系(父子关系),当组件足够多的时,组件之间就会形成“组件树”。
通信:在vue中通信就是组件之间的数据交互。父组件向子组件通信使用自定义属性,在子组件中使用props接收;子组件向父组件通信,使用自定义事件,在子组件中使用this.$emit(‘自定义事件’,‘数据’)回传数据。
什么是MVVM框架
MVVM流程:M数据层,VM虚拟DOM层,V视图层
MVVM的优点:低耦合,可重用性,独立开发
动态组件
被<keep-alive>所包裹的组件就是动态组件,并且这个组件是不会被销毁的,相当于是组件的一种缓存。
被动态组件包裹过的组件多了两个生命周期钩子activated(激活),deactivated(休眠)
activated和mounted的区别
activated可以执行多次,mounted只能执行一次。
deactivated和beforeDestroy的区别
deactivated可以执行多次,而beforeDestroy只能执行一次
什么是插槽
插槽就是子组件提供给父组件使用的一个占位符,用<slot></slot>表示,父组件可以在插槽中填充任何代码,填充的内容会替换子组件的<slot><slot/>标签。
什么是具名插槽
具名插槽就是给插槽取个名字,一个子组件可以放多个插槽,而父组件填充内容的时候可以根据名字把内容填充到对应的插槽中。
什么是作用域插槽
作用域插槽就是绑定数据的插槽,组件内变量绑定在上,使用v-slot指令,变量上就会绑定传递的属性和值。
组件中data为什么是一个函数,new Vue实例是一个对象
因为组件是用来复用的,且在js里的对象是引用关系,如果组件中的data是一个对象,那么作用域就没有隔离,子组件中的data属性值会互相影响,如果组件中的data是一个函数,那么每个实例都会返回一个对象,组件之间的data属性值不会互相影响;而new Vue的实例不会被复用的,所以不存在引用对象的问题
vue2和vue3的区别
- 双向数据绑定发生变化:vue2双向数据绑定是利用ES5的object.defineProperty()对数据进行劫持,在结合发布订阅模式来实现的;vue3中使用ES6的ProxyAPI对数据代理
- 根节点:vue2是单一根节点;vue3是多根节点。
- API:vue2使用选项类型API(Options API),用属性来分割组件;vue3使用组合型API(Composition API),用方法来分割组件
- 数据建立:vue2把数据放在data中;vue3使用setup方法,在组件初始化的时候vue触发
- 生命钩子发生变化:
vue2 vue3 beforetCreate setup() created setup() beforeMount onBeforeMount mounted onMounted befoeUpdate onBeforeUpdate updated onUpdated beforeDestroy onBeforeUnmount destroyed onUnmounted activated onActivated deactivated onDeactivated - 传参不同:
父传子:vue3通过props接收并通过toRefs转成响应式toRefs(props)
子传父:在vue2中会调用到this.$emit然后传入事件名和参数对象,vue3中没用this,只能通过setup中的参数 传递。
- vue3较vue2体积小,速度快
- 在vue2中,主要使用的是观察者模式,不管数据多大,都会对数据进行创建检查;vue3对数据进行懒观察,仅对可见部分数据进行懒观察。
vue3里为什么要用Proxy替代defineProperty
defineProperty的弊端:
- vue2是通过object.defineproperty中的getter和setter函数进行数据劫持完成数据响应的
- 无法直接监听属性的改变
- 无法直接监听数组
proxy的优势:
- 作为vue3中替代defineProperty的API,相当于给一个对象的外层加了一层拦截,这层拦截可以对信息的过滤,修改。
- 因为是在整个对象外层加了一层拦截,所以操作对象中的属性同时监听属性的变化
- 可以直接监听数组变化
说一下nextTick是做什么的
nextTick()是将回调函数延迟在下一次Dom更新数据后调用,简单理解:当数据更新了,在dom中渲染后,自动执行该函数,next Tick多次调用会维持一个数组,之后会异步的把数组中的方法执行,这样就会在视图更新之后获取到真实的DOM元素。
nextTick和$nextTick的区别
- nextTick():当数据发生变化,更新后执行回调,在下次DOM更新结束之后延迟回调,在修改数据之后立即执行这个方法,获取更新后的DOM
- $nextTick():当DOM发生变化,更新后执行回调。将回调延迟到下次DOM更新之后执行。在修改数据立即使用它,然后等待DOM更新。
- 区别:nextTick(callback)是全局的方法;$nextTick(callback)是回调的this自动绑定到调用它的实例上
SPA单页面的理解,它的优点缺点分别是什么
SPA0(single-page application)仅在Web页面初始化时加载响应的HTML,JS和CSS。一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载和跳转;取而代之的是利用路由机制实现HTML内容的变化,UI与用户的交互,避免页面重新加载。
优点:
- 用户体验好, 内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
- 基于上面一点,SPA相对对服务器压力小
- 前后端分离,架构清晰,前端进行交互逻辑,后端负责数据处理
缺点:
- 初次加载耗时多,为实现单页web应用功能及显示效果,需要统一加载,部分页面按需加载
- SEO难度较大:由于所有的内容都在一个页面中动态显示,所以在SEO上有着天然的弱势
标签:...,面试题,vue,自定义,插槽,前端,vue3,组件,数据 来源: https://www.cnblogs.com/wang622/p/16590424.html