前端面试题整理
1.谈谈px,em,rem的区别
px是相对于显示器屏幕分辨率而言的px是相对于显示器屏幕分辨率而言的
em是相对长度单位。相对于当前对象内文本的字体尺寸
rem相对的只是HTML根元素
2.call 和 apply的区别,哪个的性能好一些
区别 :传参不同 call()可以多个参数,apply只能传两个参数 . call性能好一些
3.闭包是什么?有什么特性,在什么情况下比较实用
(1) 闭包是指有权访问另一个函数作用域中的变量的函数。(这与当函数被调用是会创建一个执行函数和相应的作用域链。作用域链本质上是指向变量对象的指针列表,只引用,不实际包含变量对象)。作用域链中,函数内部变量对象优先级最高,然后,由最近的外部函数依次向后排。
(2) 封闭性:外界无法访问闭包内部的数据,如果在闭包内声明变量,外界是无法访问的,除非闭包主动向外界提供访问接口; 持久性:一般的函数,调用完毕之后,系统自动注销函数,而对于闭包来说,在外部函数被调用之后,闭包结构依然保存在。
(3) 缺点:由于闭包携带包含它函数的作用域,因此比其他函数占用的内存更多。
优点:减少创建全局变量 减少传递给函数的参数量 封闭性
(4)闭包可以读取函数内部的局部变量;这些变量的值始终保存在内存中
函数执行后,函数执行环境的作用域会被销毁,但是活动对象不会销毁,只有将匿名函数销毁后才可以销毁活动对象。可以将保存函数的变量赋值为null,将可销毁匿名函数作用域。
常见创建闭包方法:在一个函数内部创建另一个函数。
4.Promise、async与await的区别,执行顺序分别是什么
知识点
显然,这考察的是js中的事件循环和回调队列。注意以下几点:
- Promise优先于setTimeout宏任务。所以,setTimeout回调会在最后执行。
- Promise一旦被定义,就会立即执行。
- Promise的reject和resolve是异步执行的回调。所以,resolve()会被放到回调队列中,在主函数执行完和setTimeout前调用。
- await执行完后,会让出线程。async标记的函数会返回一个Promise对象
难点
最令人困惑的,就是async1 end在promise2之后输出
在函数async1中,执行promise(由于async2是async标记的函数,所以默认返回promise对象)会发现resolve(),然后放入回调队列。
接着执行下方的new Promise中的resolve()输出promise2,再回来输出async1 end。
http://www.javanx.cn/20181105/promise-or-async-await/
5.es6如何克隆一个对象,深浅拷贝的api又是哪几个,数组的深浅拷贝又有哪些方法
浅克隆
直接赋值 =
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
结构赋值
let object1 = {
a: 1,
b: 2,
c: 3
};
let object2 = {...object1};
object1.a=11;
console.log(object1);
> Object { a: 11, b: 2, c: 3 }
这也是浅拷贝
深可能
最简单的深拷贝(JSON.stringify() 和JSON.parse())
遍历取值赋值 for…in
数组 concat
6.谈谈你对this的理解
this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象,指向window对象时可以省
7.es6数组去重的办法有哪些
function unique(arr) {
const res = new Map();
return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
function unique(arr) {
return Array.from(new Set(arr))
}
function unique(arr) {
let arr2=[]
arr.map(item=>{
if(arr2.indexOf(item)==-1){
arr2.push(item)
}
})
return arr2
}
function unique(arr) {
return new Array(...new Set(arr))
}
8.es6如何获取数组中最大的值,有什么快捷的方法
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
9.谈谈Array.prototype.some 和 Array.prototype.every的区别
every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
10.Array.prototype.reduce有什么适用的场景
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
},10);
console.log(sum); //25
11.Vue有哪几种导航钩子,分别是什么
1) 全局钩子函数:定义在全局的路由对象中,主要有:
beforeEach:在路由切换开始时调用
afterEach:在每次路由切换成功进入**阶段时被调用
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// do something
next();
});
router.afterEach((to, from, next) => {
console.log(to.path);
});
每个钩子方法接收三个参数:
to: Route : 即将要进入的目标 [路由对象]
from: Route : 当前导航正要离开的路由
next: Function : 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next
方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from
路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
确保要调用 next方法,否则钩子就不会被 resolved。
2)单独路由独享的钩子:可以再路由配置上直接定义beforeEnter 钩子
3)组件的钩子函数:定义在组件的router选项中
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
let fromPath = '';
export default{
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当钩子执行前,组件实例还没被创建
fromPath = from.path;
next();
},
}
12.Vuex是什么,在什么场景比较适用,谈谈mutations与actions的区别,你觉得modules在什么情况下比较适用。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
1、action主要处理的是异步的操作,mutation必须同步执行,而action就不受这样的限制,也就是说action中我们既可以处理同步,也可以处理异步的操作
2、action改变状态,最后是通过提交mutation
13.Vue-router是什么,它有哪些组件?谈谈vue-router的理解
路由
14.Vue数据双向绑定的原理是什么
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter 这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的 update() 方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
15.Vue的生命周期有哪些,谈谈对它们的理解
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后
在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
在created阶段,vue实例的数据对象data有了,$el还没有。
载入前/后
在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后
当data变化时,会触发beforeUpdate和updated方法。
销毁前/后
16.Slot普通插槽和具名插槽的区别
name
17.Vue内置的动态组件是哪个,通过什么属性来加载不同的组件?
1、使用import导入组件,可以获取到组件
2、使用import导入组件,直接将组件赋值给componet
3、使用require 导入组件,可以获取到组件
4、使用require 导入组件,直接将组件赋值给componet
18.创建低开销的静态组件应该给组件加什么属性
v-once
19.Vue的混入是什么?
Mixins
20.Vue深度作用选择器是什么?
>>>
21.Vue中的CSS Modules的用处
css modules是一种流行的模块化和组合CSS的系统。 vue-loader提供了与css modules的集成,作为scope CSS的替代方案。