经历了年初的面试,总结了一些面试常问的问题(html+css+js基础+vue)
css部分
-
css3的动画了解吗?有哪些属性?
定义动画通过@keyframs关键字定义。
使用时属性如下(部分列举):
animation-name:动画名字
animation-duration:动画耗时
animation-iteration-count:动画播放次数
animation-direction:是否反复播放该动画,播放次数为1时,设置无效 -
css3的过渡属性transform呢?
有以下属性:
translate:平移
scale:缩放
rotate:旋转 -
垂直居中的方法(主要问flex)
(1)定位+margin+translate
(2)flex布局 -
rem用过吗?
是相对于设置在根元素上的字体大小的相对单位。
-
BFC了解吗?哪些属性会对里面的元素产生影响?
块级格式化上下文,一个独立的区域,盒子外的元素不会对其中的元素产生影响。
float属性不为none
position为absolute或fixed
display为inline-block, table-cell, table-caption, flex, inline-flex
overflow不为visible(反之即可产生影响) -
网页自适应你怎么做?
通过媒体查询和flex结合。
js基础
-
数据类型(高频)
基本数据类型:String,Number,Boolean,null,undefined,Symbol
引用类型(复杂数据类型):Object,Array,Function -
基本类型和引用类型的区别?
基本类型值在栈内存值占据固定大小
引用类型值为对象,保存在堆值,栈内存中保存着指向该对象的指针(地址) -
如何实现数据的深浅拷贝?
浅拷贝:定义变量,简单地将需要拷贝的对象赋值。
深拷贝:针对数组:slice,concat,扩展运算符…(一维数组有效,二维数组还是浅拷贝)
针对对象:JSON.parse(),JSON.stringify()
还可以利用递归实现对象或者数组的深拷贝
// obj为需要拷贝的数组或者对象
function deepCopy(obj) {
if (!obj && typeof obj !== "object") { // 排除传入的是基本数据类型
throw new Error("error")
}
const targetObj = Array.isArray(obj) ? [] : {}
for (let key in obj) { // 只针对对象自有属性进行拷贝
if (obj[key] && typeof obj[key] === "object") { // 如果为对象,利用递归进行再次拷贝,直到为基本类型为止
targetObj[key] = deepCopy(obj[key])
} else {
targetObj[key] = obj[key]
}
}
return targetObj
}
-
事件委托的原理
利用事件冒泡
-
那么如何阻止事件冒泡呢?
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
function bubbles(e){ var ev = e || window.event; if(ev && ev.stopPropagation) { //非IE浏览器 ev.stopPropagation(); } else { //IE浏览器(IE11以下) ev.cancelBubble = true; } console.log("最底层盒子被点击了") }
-
bind,apply,call的区别(高频)
都可以改变this指向,第一个参数都为要改变的那个对象,区别在后面的参数。
apply以数组的形式传入参数,立即执行函数。
call以arg1,arg2,arg3…的形式传入参数,立即执行函数。
bind与call类似,不会立即执行函数,而是返回一个新的函数。 -
闭包
就是可以读取其他函数内部变量的函数
function outer() { var a = "变量1" var inner = function () { console.log(a) } return inner }// inner为一个闭包函数,因为他能够访问outer函数的作作用域
-
作用域和作用域链
全局作用域,局部作用域,es6新增的块级作用域(let,const)
作用域链我的理解就是,根据在内部函数可以访问外部函数变量,找不到再往上层作用域查找,形成了一个作用域链。 -
es6新特性有哪些常用的?
let,const,箭头函数,解构赋值,扩展运算符…,新增基本数据类型Symbol(表示独一无二的值),Map和Set,数组新方法(find(),fineIndex()),promise,async/await
-
箭头函数的优缺点以及怎么改变箭头函数的this(高频)
[箭头函数知识参考链接](https://juejin.im/post/5aa1eb056fb9a028b77a66fd#heading-3)
- 原型以及原型链(高频)
原型:每一个构造函数都有的属性prototype
原型链:当查找当前对象的属性的时候,如何没有,就会去原型上查找,如果还没有,就往上查找,一直找到Object,形成了一个原型链。
- 代码执行顺序(宏任务,微任务)
宏任务队列(macro-task):a1,a2,a3
微任务队列(micro-task):b1,b2,b3
执行顺序:a1执行完毕,会依次执行b1,b2,b3,执行完清空微任务队列的任务,接着执行a2,以此循环。
- window.onload和$(function(){})有什么区别?
前者如果有多个方法,会被覆盖,只会执行最后一个,在页面元素(图片,引用等)全部加载完毕才会执行其中的函数,同$(window).load(function(){})
后者如果有多个方法,都会执行,在页面内容(图片等)加载完成之前会执行其中的函数,同$(document).ready(function(){})
- 如何实现同域名下两个已经打开的标签页之间的通讯?
使用localStorage,在另一页面监听storage事件,利用事件对象e得到值
剩余方法参考链接:[实现标签页的通讯](https://blog.csdn.net/weixin_42367621/article/details/80549653)
- 数组的方法,slice,splice有什么区别?那个会返回一个数组?
slice:截取数组,浅拷贝,返回新数组,原数组不会被改变。
splice:用来添加,替换,删除数组,返回被修改的内容,会改变原数组。
- split和join的用法
split:字符串方法,分割字符串
const str = 'xiaoming';
const words = str.split('');
console.log(words);// ["x", "i", "a", "o", "m", "i", "n", "g"]
const words2 = str.split(' '); // 注意:与''有区别
console.log(words2);// ["xiaoming"]
const words3 = str.split('a');
console.log(words3);// ["xi", "oming"]
join:数组方法,将数组元素拼接成字符串
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());// "Fire,Air,Water"
Vue部分
-
生命周期函数
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是Vue的生命周期。
生命周期 | 描述 |
---|---|
beforeCreate | 组件实例被创建之初,组件的属性生效之前 |
created | 组件实例已经完全创建,属性也绑定,但真实dom还没有生成,$el还不可用(可以访问data) |
beforeMount | 在挂载开始之前被调用:相关的 render 函数首次被调用 |
mounted | el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子 |
beforeUpdate | 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前 |
update | 组件数据更新之后 |
activited | keep-alive专属,组件被激活时调用 |
deadctivated | keep-alive专属,组件被销毁时调用 |
beforeDestory | 组件销毁前调用 |
destoryed | 组件销毁后调用 |
errorCaptured | 2.5.0+新增,当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。 |
-
v-if和v-show的区别
v-if会直接销毁元素,v-show会切换元素的display属性。
-
v-if和v-for一起使用的问题
v-for会有更高的优先级。
附上官网链接 -
组件之间通讯的方式有哪些?
父子组件:props,$emit
兄弟组件:eventBus,Vuex -
Vue-router的钩子(路由守卫)
-
全局守卫:
router.beforeEach 全局前置守卫 进入路由之前
router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
router.afterEach 全局后置钩子 进入路由之后 -
路由独享守卫:可以为单独的路由设置守卫,在全局守卫之后执行
-
路由组件内的守卫
beforeRouteEnter:进入路由前, 在路由独享守卫后调用 不能 获取组件实例 this,组件实例还没被创建
beforeRouteUpdate (2.2): 路由复用同一个组件时, 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 this
beforeRouteLeave: 离开当前路由时, 导航离开该组件的对应路由时调用,可以访问组件实例 this
- 如何理解单项数据流