1、js基础知识(手写代码) Q:js 数据类型有哪些,函数是按值传递还是引用传递,symbol数据类型有了解过吗,应用场景有哪些 ?
Z: 原始数据类型有:boolean、string、number、undefined、null、object 、symbol
函数传递参数是引用传递,但是如果把传递进来的参数,赋值给另外一个变量,函数执行过程中,会重新分配一块地址
sysbol是es6新定义的一种新的数据类型,目的是为了防止对象属性名冲突,保证对象的属性名都是独一无二的
Q: typeof 和instanceOf判断有什么区别,instanceOf判断的原理 ?
Z:typeof运算符只能判断基础的数据类型,'string'、'number'、'boolean' 等
instanceof运算符是根据原型链来判断,本质其实是检测某个实例对象原型链上,是否存在构造函数的protptype属性
Q:严格模式下的this指向哪里?
Z:1.全局中,this指向window,全局函数中this指向undefined
2.构造函数中的this指向调用它的实例
3.事件处理函数中的this, 指向出发事件的对象节点
Q:数组和对象深浅拷贝的方法都有哪些,深拷贝大概的实现思路?
Z:实现浅拷贝的方法有:object.assign()、展开运算符(...)
当要实现一个深拷贝的方法,实现思路分为拷贝+递归,判断当前属性是否是对象(Reflect.ownKeys),如果是对象,就进行递归操作。
在拷贝的过程中,要注意处理这几种情况
1.深拷贝数组的情况
2.考虑null的情况
3.考虑Symbol的情况
4.考虑循环引用的情况
Q:如何理解原型和原型链
Z:原型是一个对象,存有对象上所有的共有的属性和方法,然后让每个对象的_proto_属性去存这个地址,其实原型的出现是为了减少不必要的内存开销
原型链就是通过_proto_向当前实例所属类的原型上查找属性和方法的机制,如果找到object原型上还是没有找到想要的方法或者是属性就查找结束
Q:proxy了解过吗,可以实现哪些功能 ?
Z:proxy用来创建对象的代理,vue3将会通过proxy来实现数据响应式,vue3要用proxy代替原本的api,不必要一层层递归为每个属性一层层添加代理,一次操作,原本更新监听不到的操作就可以监听到了,性能更好,缺陷就是浏览器的兼容性变差了
Q: js 有几种方式实现异步 ?
Z:回调函数,假设多个请求具有依赖性,容易导致回调地狱
promise,实现了链式调用,如果在then中return,那么会return的值将会被Promise.resolve()包装
async/await ,实际上是一个语法糖,async 其实会返回一个promise, await在等待函数内部返回的promise对象或者其他值,应用场景一般使用在,有一个函数的执行,每一步都依赖上一步执行完成再去执行
Q:手写promise实现的思路 ? (笔试题),手写new,
Q:event loop 执行顺序 ?
Z: 1.一个脚本作为宏任务先执行
2.执行过程同步代码先执行,宏任务进入宏任务队列,微任务进入微任务队列,
3.宏任务先执行完开始执行微任务列表,直到全部都执行完
4.检查浏览器ui线程渲染工作
5.检查是否有web worker,有就执行
宏任务:script, settimeout , settimeinterval
微任务:promise, V8回收机制,
Q:思考call、apply、bind实现原理
相同点,都是用来改变执行上下文,改变this的指向
bind是不会立即调用的,而是返回绑定之后新的函数
apply立即调用,返回函数的执行结果,第一个参数为执行作用域,后面跟上一个数组
call 立即调用,返回函数的执行结果,第一个参数为执行作用域,后面跟上多余的参数
Q: new一个对象发生了什么事情
1.开辟一块内存空间
2.链接到原型
3.绑定this
4.返回新的对象
2、浏览器相关 Q:事件触发的过程是怎么样的,事件代理了解过吗?
事件触发分为三个阶段
1.window往事件触发的地方去传播,遇到注册的捕获事件会触发
2.传播到事件注册的地方
3.事件触发往window传播,遇到注册的冒泡事件会触发
事件代理就是,本来应该绑定在子节点上的事件,在父节点上代理去实现,节约内存,多个子节点,无需多次绑定
Q:浏览器跨域的方式有几种?
1.JSONP 通过script标签,指定一个请求,请求后面跟上要执行的回调函数来实现,但是jsonp仅限于get请求
2.CORS 需要后端配合实现, 服务器设置http响应头,
Q:说一下回流和重绘?
1.对dom结构修改,引起几何尺寸发生变化的时候,会发生回流,由于dom的结构发生改变,所以需要重新计算样式,生成布局树,建立树图层,浏 览器渲染的那一套要重新走一遍,开销很大
2.dom的修改引起样式变化,发生重绘,由于dom节点的位置并没有更新,所以不需要重新渲染树,直接进入分块的后续操作
Q:输入url到页面展现,发生了什么
1.发送请求,查找缓存,进行dns解析
2.建立tcp连接,发送http请求
3.构建css样式树,构建dom节点树,渲染页面ui
Q:AST语法树了解过吗
ast语法树应用比较广泛,例如编辑器自动补全,webpack通过babel对js进行转义
js执行的第一步就是读取js文件流,在经过语法分析生成ast, 最后生成机器码执行
语法分析主要分为两部:
1、分词,将代码分割成最小的单位
2、词法分析,将分词的最小的单位建立连接
Q:为什么TCP需要三次握手,四次挥手 ?
1、第一次握手,客户端向服务器发送请求,请求准备建立连接
2、第二次握手,服务器接受请求数据包,允许建立连接
3、第三次握手,客户端发送数据给服务端
为什么要挥手是第四次,因为最后一次挥手是客户端要想服务器传输断开连接的信息,断开连接的信息需要分开传输,如果是在前面连接的阶段就带有断连的信息,服务器会来不及处理,因此需要第四次挥手,分开传输
3、打包工具webpack的面试题
Q: 什么是bunble、chunk、module
bunble是打包出来的文件,chunk是webpack在进行模块依赖分析的时候,代码分割出来的代码块,module是开发中的单个模块
Q:loader和plugin有什么区别?
loader其实就是告诉webpack, 如何转换某一类型的文件,怎么引入到打包的文件中,常见的loader有,css-loader, babel-loader, image-loader
plugin作用更大,可以做资源的管理,优化打包,注入环境变量等
Q:webpack打包原理, 手写过webpack插件吗 ?
webpack是一个静态模块打包工具,在构建项目的时候,会递归的构建一个依赖试图,包含了应用程序的每个模块,然后将这些模块打包成一个个文件
过程分为以下几步:
1.识别入口文件 2.通过逐层识别模块依赖 3.webpack分析代码,转换代码,编译代码,输出代码 4. 最终形成打包之后的代码
没写过插件XXXXXXXX
Q:如何优化减少webpack打包的时间,如何减少项目打包之后的体积 ?
减少webpack打包时间
1.优化loader, 例如可以优化babel插件查找文件的范围,限定在src下面,因为mode_modules里面的文件,都是编译过的
2.externals 配置常用的库
3.Happypack 开启并行打包,可以优化加载速度
4.webpack-uglify-parallel 优化加载速度
如何减少打包之后的体积
1.压缩代码
2.利用cdn加速
3.提取公共代码
Q: vite了解过吗, 和webpack对比有什么好处 ?
当项目越来越大,webpack会出现以下问题
1.webpack dev server冷启动时间较长
2.热更新速度比较慢
原因是因为webpack dev server在构建的时候,会把所有的代码文件build一遍,需要的时间较长
vite的特点
1.轻量
2.按需打包
3.热渲染依赖
vite没有打包相关的操作,当vite server服务启动的时候,中间件会进行打包注入相关操作,所以真正实现了按需加载
Q:webpack配置多页应用
webpack的多页应用通过入口entry和多实例html-webpack-plugin配合来构建,html-webpack-plugin的chunk属性传入对应的entry的key就可以做到关联
4、vue / uniapp 面试 Q:什么是mvvm?
m代表model数据模型层,v代表视图层,vm是数据层和视图层的桥梁,数据绑定在vm层,会自动渲染在页面中,视图变化的时候,也会通知vm层更 新数据
Q:vue2.x版本数据响应式原理,怎么实现数组更新,再说下3.X版本数据响应式原理
1.vue初始化组件的时候,会使用object.defineProperty 重新定义一遍data里面的所有属性,这里是一个经典的发布订阅者模式的应用,当页面使用相 应的数据时候,首先会进行依赖收集,如果数 据发生变化,会通知相应的依赖进行更新操作、
2.vue2采用函数劫持的方式,实现的数组更新,vue将数组的原型链部分方法重写,指向自己函数原型方法,这样可以达到调用数组方法也可以通知依 赖更新
3.vue3.X版本实现响应式原理,用proxy代替了object.defineProperty() 方法,因为proxy可以直接监听数组和对象的变化,proxy其实只能代理到数据的 第一层,对于这个问题,vue3是通过Reflect.get() 属性来判断返回值是否为object, 如果是的话,内部调用reactive(接受一个普通对象,返回一个响应 式对象)处理,
Q:nextTick实现原理是什么 ?
nextTick其实主要依赖于宏任务微任务执行栈,在dom更新循环结束之后延迟回调,nextTick其实是定义了一个异步方法,多次调用nextTick会将方法 存入到队列中,通过异步方法清空当前队列
Q:如何比较两个节点之间的差异diff算法 , 怎么更新节点?
diff算法比较的核心分为以下几步:
1.同级比较,再比较子节点
2.比较一方有子节点,另一方没有子节点的情况,将旧的子节点移除
3.比较都有子节点的情况,递归遍历,vue的diff算法核心中,还采取了双端比较的方法,借助key, 找到可以复用的节点
vue更新节点的过程
根据真实的dom树构建virtural dom, 当virtural dom中有数据更新,生成一个新的vnode, 找到对应的节点,在真实的dom节点上打补丁实现
Q:说一下v-model的原理?
v-mode实际上是一个语法糖,其实可以看做是 value+input事件的语法糖,在编译的时候,其实会根据对应的标签打上不同的事件和属性
Q:vue模板编译了解过吗 ?
简单来说,模板编译就是将<template></template>转换成render的过程
分为以下几步
1.生成ast语法树,利用正则表达式对模板进行解析
2.优化,vue数据是响应式的,但是很多数据在一开始渲染之后后面就不会再改变,这个时候的优化就很有必要了,需要深度遍历ast语法树,将不需 要改变的节点标记为静态节点,在运行的时候会跳过对比,这就运行时的模板起了很大的优化作用
3.将ast转换为render函数
Q:computed和watch有什么区别 ?
computed本质是一个具备缓存的watcher, 依赖的属性变化就会触发视图的变化,适用于消耗性能的场景,当模板中放入过多的逻辑会让模板难以维 护,可以将复杂的逻辑放入到计算属性中处理
watch没有缓存属性,只是起到观察作用,可以监听数据的变化,然后执行回调, 如果需要深度监听对象中的属性,可以开启deep:true
Q:SSR了解过吗 ?
SSR也就是服务端渲染,其实也就是在vue中把标签渲染成html的工作放在服务端完成,然后再把html然会给客户端
服务端有着更好的SEO 首屏加载快的优点,同时也会有一些限制,比如服务端只有beforeCreate和created钩子函数,服务端渲染应用程序时,需要处 于node环境,再就是会造成服务端较大的负载需求
Q:前端路由实现的原理,两种方式有什么区别?
前端路由的原理本质就是监听页面url变化,然后根据路由匹配规则,展现当前页面
hash路由:
监听hasChange事件,监听#之后的值的改变,进行页面跳转,服务端收到的永远都是一级域名
history模式:
通过history模式同样不会刷新当前页面,只会更新浏览器的历史纪录
两者模式的比较
1、hash模式只会更改#之后的内容,history模式可以设置任意同源URL
2、history模式可以通过浏览器api将任意url添加到历史记录中,hash模式只能更改hash值
3、hash模式兼容性好,无需后端配置,history模式要在用户手动输入地址匹配不到页面的时候,后端需要适配index.html页面
Q:vue做过哪些优化?
1.减少data里面的数据,因为data里面的数据都会增加getter和setter,会收集对应的依赖
2.keep-alive做缓存
3.key保证唯一
4.做防抖节流
5.使用路由懒加载,图片懒加载
6.v-for循环的情况,添加事件代理
7.防抖节流
Q:父子组件加载的顺序 ?
1.加载进来的过程是
(父) beforeCreate -> (父)created -> (父)beforeMount -> (子) beforeCreate -> (子) created -> (子) beforeMounted -> (子)mounted -> (父) mounted
Q:优化首屏加载?
1.首先就是分析前端加载速度慢的原因,安装可视化的工具,webpack-bundle-analyzer , 安装插件,会暴露出问题
2.对js文件分离打包,把一些大的js文件资源放在内网或者cdn引入
3.vue路由实现懒加载
4.图片压缩,字体用在线字体
5.用webpack开启gzip压缩,提高http请求传输效率
6.vue代码层面书写的优化,用关键key缓存,v-if不要和v-for混用
Q:$route 和 $router 有什么区别 ?
$route是当前活跃的路由对象,router是创建出来的实例,用来实现路由导航守卫。
5、css面试题
Q:说一下BFC ?
BFC是指,格式化上下文之后,外部元素的布局不会影响到内部元素,内部元素也不会影响到外部元素,创建BFC的情况有,浮动,绝对定位,行内块 元素
Q:画三角形的原理 ?
边框等分的原理,设置宽度高度为0,border宽度设置,border颜色设置
Q:rgba 和 opacity 的区别
rgba设置的透明图不具备继承属性,但是opacity会继承父元素的属性
Q:box-sizing 具有哪些属性 ?
content-box, border-box, 继承
Q:怎么实现小于12px的字体
transform:scal 属性来实现
Q:BEM命名规范了解过吗 ?
有三种连接的方式
- 中划线:表示单词之间的连接符号
__双下划线表示连接块和块的子元素
_单下划线表示连接元素的一种状态
6.自己在项目的总结 Q:说说你怎么在项目中封装组件的 ?
Q:说说你怎么封装的移动端点击事件 ?
Q:说说你怎么做到的封装的axios ?