面试

1▲ Vue 中双向数据绑定的实现原理是怎样的?
vue数据双向绑定的原理是通过数据劫持结合发布订阅模式,通过Object.defineProperty方法来劫持每个属性,为每个属性添加setter和getter,当数据变动时,发布消息给订阅者,触发相应的监听回调
整个mvvm框架的主要模块分别为:
1、observer:进行数据的劫持,get函数触发时,添加订阅者,set函数触发数据watcher,进行视图更新
2、compile:对元素节点进行扫描和解析,初始化dom,订阅数据变化通知watcher跟新视图
3、watcher:添加订阅者,收集属性变动,执行视图更新
4、mvvm入口函数

2vue中的数据是如何被渲染的
1、创建实例,并进行初始化,
2、模板编译(把真实的dom元素进行转换成一个对应的dom对象,并描述与数据的绑定关系),生成render函数(这个函数是就构建虚拟DOM所需要的工具)
3、对数据进行监听,
4、数据变化执行render函数,生成新的vNode对象
5、对比新旧节点,通过diff算法对节点进行更新,最终编译成真正的dom结构渲染
3简述浏览器的渲染过程,重绘和重排在渲染过程中的哪一部分?
浏览器进程:
browser进程:
第三方插件进程:
GPU进程:
浏览器渲染进程:浏览器内核(主要负责渲染页面,js的执行,事件循环等)
浏览器内核线程:
GUI渲染线程:负责渲染界面,解析html,css,构建DOM和renderTree,(互斥)
JS引擎线程:负责处理javascript的脚本执行,(互斥)
事件触发线程:用来控制事件循环
定时触发器线程:定时器和延时器的所在线程
异步http请求线程:处理http请求
4hash和history
是前端路由的两种模式,可以记录当前页面的状态,实现浏览器的前进和后退
hash:拼在url的尾部,通过#来拼接,hash值变化不会导致页面发生请求,对后端没有影响,不利于seo
hsitory:可以在url添加参数,利用了h5 的History Interface 中新增的pushState和replaceState方法,特别需要后端的配合,缺点也是刷新可能无法获取资源
5Vue 组件间是如何进行通信的?
1.父子组件
父-子 props 子-父emit 2.vuex state,mutation,actions,getters modules 3.祖孙组件 provide和inject 允许祖先组件向子孙后代注入一个依赖,不论层次有多深,只要能够构成上下游的关系 缺点:当多个后代组件同时依赖同一个父组件提供数据时,只要任一组件对数据进行了修改,所有依赖的组件都会 受到影响,实际上是增加了耦合度。 任意层级访问使数据追踪变的比较困难,你并不能准确的定位到是哪一个层级对数据进行了改变,当数据出现问题时,尤其 是多人协作时,可能会大大增加问题定位的损耗。 4.eventBus:全局事件总线 Vue.prototype.EventBus = new Vue() vue的原型上挂载一个new Vue()
发送事件:this.emit()
接收事件:off()

    缺点:单页面程序刷新会移除所有的eventbus,当前的业务可能会断裂,所以切记在页面销毁的时候移除
    原理:它的工作原理是发布/订阅方法,通常称为 Pub/Sub 。两个方法$on和$emit。一个用于创建发出的事件,它就是$emit;另一个用于订阅$on:

6简述虚拟 dom 实现原理,简述 diff 算法的实现机制和使用场景

虚拟DOM(Virtual DOM) 用js用对象的方式来表示Dom结构,即,将Dom的变化对比放在js层

为什么使用虚拟dom:首先页面展示需要进行对html和css解析生成对应的dom树和样式树,最后合并生成rendertree,然后布局绘制进行展示,
但是在绘制布局过程中,操作js会导致重排和重绘,这样就会导致dom树的重新渲染,非常消耗性能。
    虚拟dom 就是为了解决这个问题,首先将dom生成一个对象,操作dom先去修改这个对象,最后统一完成dom树的重新构建
    所以需要提供转换的方法:dom -> obj   obj -> dom 等方法
diff算法:主要是用来比较两棵树的变化之处,得到一个发生变化的节点列表组成的对象,正常的时间复杂度为O(n*3),但是很少有dom元素跨层级移动的情况,所以,一般是平层比较两棵树,时间复杂度为O(n),放弃了深度遍历。
    一般diff需要处理四种情况:
        1、REPLACE : 元素节点类型发生变化,
        2、PROPS : 元素节点类型不变化,属性或者属性值发生变化
        3、TEXT : 文本发生变化
        4、REORDER : 元素的移动,包括增加和删除

7简述什么是 XSS 攻击以及 CSRF 攻击?
XSS攻击(Cross Site Scripting)全称跨站脚本攻击(让用户恶意的执行脚本代码),是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它
用户使用的页面中。
预防: 对重要的 cookie设置 httpOnly, 防止客户端通过document.cookie读取 cookie,此 HTTP头由服务端设置。
将不可信的值输出 URL参数之前,进行 URLEncode操作,而对于从 URL参数中获取值一定要进行格式检测
CSRF (Cross Site Request Forgery)攻击,(让用户恶意的调取接口)中文名:跨站请求伪造。其原理是攻击者构造网站后台某个功能接口的请求
地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用
户合法的操作。对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不是百分百安全,攻击者可诱导用
户进入带 Form 表单可用POST方式提交参数的页面。
目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段(referer能够得到访问的请求来源地址);在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证。
8性能优化(重点)
了解浏览器渲染机制
1. 解析 HTML 文件,构建 DOM 树,同时浏览器主进程负责下载 CSS 文件
2. CSS 文件下载完成,解析 CSS 文件成树形的数据结构,然后结合 DOM 树合并成 RenderObject 树
3. 布局 RenderObject 树 (Layout/reflow),负责 RenderObject 树中的元素的尺寸,位置等计算
4. 绘制 RenderObject 树 (paint),绘制页面的像素信息
5. 浏览器主进程将默认的图层和复合图层交给 GPU 进程,GPU 进程再将各个图层合成(composite),最后显示出页面
1、网页首页渲染减少http请求
2、js会阻止dom构建,可以async
3、操作dom优化,减少重排和重绘,重排的操作影响大于重绘,使用框架例如vue,能够实现虚拟dom+diff算法来优化
4、对于图片可以使用懒加载
5、事件绑定优化:事件委托(减少注册时间,减少内存占用)防抖和节流
6、缓存优化
7、vue相关优化:
1、css文件放入单独的文件,然后引入
2、组件懒加载
9简述 Javascript 原型以及原型链
原型是Function上的一个属性,它定义了构造函数构造出对象的共有祖先,通过该构造函数构造出来的对象可以继承原型的属性和方法,原型也是对象
原型链,当函数被new操作符操作的时候,会创建出一个对象,该对象中有一个proto属性指向原型对象,这样实例就可以访问圆形的属性和方法,原型也是一个对象
所以,原型也是有原型的,因此构成了一个链式结构,原型链的终端是Object.prototype.proto => null
10继承的常见方式
(1)原型链继承
Child.prototype = new Parent()
特点:无法向父类传参,继承单一,所有实例共享父类实例属性
(2)构造函数借用```
Child函数中:Parent.call(this,params)
特点:只能继承父类属性,不能继承父类原型,可以继承多个父类
(3)组合继承
function Child(name) { Person.call(this, name); }
Child.prototype = new Person();
(4)原型式形式
function obj(o){function F(){}; F.prototype = o; return new F()}
let child = obj(new Parent())
特点:以函数返回值来操作
(5)寄生组合
function obj(o){function F(){}; F.prototype = o; return new F()}
function subObj(o){let f = obj(o); o.name='name'; return o} 这一步可以为实例传参
(6)extends
class Child extends Parent{
conscturtor(){
super()
}
}
11 简述 Vue 的生命周期
生命周期函数:在vue实例从创建到销毁的整个过程中不同阶段的自执行函数,
beforeCreate:实例初始化,但是数据,事件,Dom等都是undefined
created:数据和事件初始化,可以在created函数中得到
beforeMount:挂载之前,DOM初始化完成,
mounted:完成挂载
beforeUpdate:数据更新前的回调,数据还未变化
updated:数据更新后的回调,数据已经修改完成
beforeDistory:实例销毁之前
distoryed:实例销毁之后
activated:keep-alive激活
deactivated:keep-alive组件关闭
errorCapture:当捕获到子孙组件的错误时触发

12 简述浏览器的缓存机制
首先,浏览器和服务器之间的通信方式为应答模式,即,浏览器发起http请求-服务器响应请求,
发起请求,先去缓存中查看,缓存中没有发起http请求服务器,拿到响应数据,并根据详情数据的缓存规则,决定是否进行缓存,
将具有缓存标识的数据存入浏览器缓存
根据是否需要向服务器重新发起http请求,将缓存过程分为两个部分,分别是强缓存和协商缓存
强缓存:不会向服务器发送请求,直接从缓存中取 控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Conctrol的优先级比Expires高。
(1)public:所有内容都将被缓存(客户端和代理服务器都可缓存)
(2)private:所有内容只有客户端可以缓存,Cache-Control的默认取值
(3)no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
(5)max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
协商缓存:强缓存失效,浏览器携带缓存向服务器发起请求,由服务器更具缓存表示决定是否使用缓存的过程(eTag,信息的过期标识) 控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

13 简述虚拟 dom 实现原理,简述 diff 算法的实现机制和使用场景

虚拟DOM(Virtual DOM) 用js用对象的方式来表示Dom结构,即,将Dom的变化对比放在js层

为什么使用虚拟dom:首先页面展示需要进行对html和css解析生成对应的dom树和样式树,最后合并生成rendertree,然后布局绘制进行展示,
但是在绘制布局过程中,操作js会导致重排和重绘,这样就会导致dom树的重新渲染,非常消耗性能。
    虚拟dom 就是为了解决这个问题,首先将dom生成一个对象,操作dom先去修改这个对象,最后统一完成dom树的重新构建
    所以需要提供转换的方法:dom -> obj   obj -> dom 等方法
diff算法:主要是用来比较两棵树的变化之处,得到一个发生变化的节点列表组成的对象,正常的时间复杂度为O(n*3),但是很少有dom元素跨层级移动的情况,所以,一般是平层比较两棵树,时间复杂度为O(n),放弃了深度遍历。
    一般diff需要处理四种情况:
        1、REPLACE : 元素节点类型发生变化,
        2、PROPS : 元素节点类型不变化,属性或者属性值发生变化
        3、TEXT : 文本发生变化
        4、REORDER : 元素的移动,包括增加和删除

14 简述 Javascript 中的防抖与节流的原理并尝试实现
防抖:持续操作,只会执行最后一次回调
思想:维护一个timer,只要执行,我就先清空在赋值,让他重新开始计时,直到最后一次触发成功
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
节流:只需操作,按时执行
思想:维护一个flag开关,状态是开,执行过程中关闭,执行完再打开
function throttle(func,delay){
let run = true
return function () {
if(!run){
return
}
run = false
setTimeout(()=>{
func.apply(this,arguments)
run = true
},delay)
}
}

15 什么是闭包,什么是立即执行函数,它的作用是什么?简单说一下闭包的使用场景
闭包就是能够读取其他函数内部变量的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包可以实现防抖和节流,可以做缓存(维护一个变量的状态),可以防止命名冲突,
闭包会导致私有变量无法被销毁,造成内存大量消耗,导致内存泄露,闭包需要突破作用域连,会造成性能问题

16 简述浏览题事件循环机制
js是单线程执行的,js中的执行代码分为同步任务和异步任务,
需要一个规则来规定他们的执行顺序
首先,js引擎执行代码会先执行同步代码,会把异步任务挂起,直到同步任务执行完,异步任务执行完后会放到事件队列中,(异步事件中分为宏任务和微任务,先执行微任务队列,后执行宏任务队列)直到执行栈为空,然后执行微任务队列,再然后执行宏任务,判断宏任务中是否有同步代码和微任务,就按照这个规则来执行任务。
当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。
宏任务:settimeout setinterval setimmediate I/O UI渲染

微任务:promise process.nextTick  Object.observe(已经被废弃,异步的监视一个对象的修改)

17 localstorage 与 cookie 的区别是什么?
cookie并不适合存储,主要是用来存一些身份标识,在请求接口的时候附带上这些cookie,cookie需要进行封装,大小为4k,不同浏览器对个数有限制,每次请求都会附带,影响效率,可以对cookie属性Max Age(失效日期)domian和path(限制 cookie 能被哪些 URL 访问)
web storage 用来本地存储
session 一次会话
local 永久
18 promise 有哪些状态?简述 promise.all 的实现原理
19 简述 CORS 的用途以及基本设置 什么是跨域,什么情况下会发生跨域请求?
Cross-origin Resource Sharing 中文名称 “跨域资源共享” 简称 “CORS”,它突破了一个请求在浏览器发出只能在同源的情况下向服务器获取数据的限制
原因:浏览器限制了从脚本内发起的跨源 HTTP 请求(协议、域名、端口号)同源策略
解决方法:
JSONP:原理就是在 script 标签里面加载了一个链接请求,去访问服务器的某个请求,返回内容。
CORS: 简单请求和预检请求,当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;
前端本地代理:服务器没有跨域的概念,在配置文件中设置代理,

20 简述 JWT 的原理和校验机制
JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。
类似token,用户登录后获得后端返回的jwt,在请求资源的时候附加到请求头的Authorization
ck▲ 25 手写题库 https://github.com/Mayandev/fe-interview-handwrite
实现bind
Function.prototype.newBind = function(context,...args){
return (...newArgs) => this.apply(context,[...args,...newArgs])
}
+实现apply
Function.prototype.newApply = function(context,args){
context.fn = this
return context.fn(...args)
}
+实现call
Function.prototype.newCall = function (context,...args){
context.fn = this
return context.fn(...args)
}

▲ 8 简述 CSS 有哪些上下文类型?
层叠上下文:定位元素 > 内联元素 > 浮动元素 > 块级元素

js预编译流程
1、语法解析:检查代码有没有低级错误,
2、预编译:代码执行前,大部分是在函数执行前
3、解释执行:执行

预编译:
    创建GO,变量提升,函数提升
    
    创建AO,形参,变量,赋值undefined;形参实参统一;函数提升

Object.defineProterty 和 Proxy区别
可配置,可赋值,可枚举,value,set,get
虽然Object.defineProperty能够劫持对象的属性,但是需要对对象的每一个属性进行遍历劫持;如果对象上有新增的属性,则需要对新增的属性再次进行劫持;如果属性是对象,还需要深度遍历。这也是为什么Vue给对象新增属性需要通过$set的原因,其原理也是通过Object.defineProperty对新增的属性再次进行劫持。

相较于Object.defineProperty劫持某个属性,Proxy则更彻底,不在局限某个属性,而是直接对整个对象进行代理,Proxy不仅能够监听到属性的增加,还能监听属性的删除,比Object.defineProperty的功能更为强大

vue-router原理
不同路径展示不同资源
hash:hashchange来实现更新页面部分内容的操作
for...in for...of
for in 一般是遍历数组或对象的key值
for of 一般是遍历数组的value,通常能够遍历有iterator方法的结构

▲ 5 简述 ES6 的新特性
let,const
symbol
set,map
字符串,数组,对象新增方法
解构赋值
三点运算符
形参默认值
proxy
class
promise
gen
async/await

▲ 5 了解过 Gulp Grunt 吗?简述他们的优势以及劣势
▲ 4 Javascript 可以保存的最大数值是多少?
number类型的数据在计算机中是以IEEE754双精度存储的,但是在二进制存储的时候,会损失一部分精度
Number.MAX_VALUE
Number.MAX_SAFE_INTEGER 最大安全整数 2^53 -1
▲ 4 优化首屏渲染的方式有哪几种?
按需加载模块或者组件
路由懒加载
npx vue-cli-service build --report 可以产看打包各个模块的体积情况,从而针对性的去修改
图片懒加载
减少http请求和dom数量
▲ 3 JavaScript 中的严格模式是什么,有什么作用?
是一种规范js书写与语法规范限制的一种标准
eval()
with()
arguments.callee:正在被执行的函数
fun.caller:
变量声明重复
预编译this指向undefined
▲ 11 简述项目打包和发布的流程
▲ 7 简述浏览器的垃圾回收机制
1.标记清除:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。
2.引用计数:判断当前变量被引用的次数,判断这个变量地址被引用的次数,当被引用次数变为0,那么就会被回收
▲ 7 移动端适配有哪些方案?
▲ 6 MVC 模型和 MVVM 模型的区别
▲ 12 简述输入 URL 到浏览器显示的流程
url->判断是否有缓存,有缓存则去缓存中取
>域名解析器->ip地址->对应的资源服务器 ->
▲ 12 预编译
▲ 10 简述 Javascript 中 this 的指向有哪些

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
this的作用范围在于函数,和对象没有关系
this只会指向调用者,o.b.fn() 指向o.b
new会改变this指向,如果返回引用值类型{},[],fn,this就会指向返回值,如果返回值是原始值,就会指向实例
箭头函数的
函数定义时的this

▲ 9 简述 jsonp 的工作原理
Script 标签本身的功能就是异步加载js并且会以js的方式解析执行。一旦在script的标签里加入src的属性,浏览器执行到这个标签时就回去 请求指定的地址,如果服务器返回的是js格式的代码,甚至可以是js的函数,只要是能被js解析的,都可以被执行,这也就是jsonp的原理
▲ 9 简述 Javascript 事件冒泡和事件捕获原理
冒泡:即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点
▲ 8 如何解决 CSS 类名重名?
1.人为规定
2.作用域scoped
▲ 8 简述发布订阅模式的实现方式以及原理
▲ 8 箭头函数和普通函数的区别是什么?
1.箭头函数不能够当做构造函数,不能new操作
2.箭头函数没有arguments
3.箭头函数没有自己的this,只会捕获上下文中的this作为自己的this,该函数定义时所在的this(不是执行)
4.箭头函数无法改变this指向
5.箭头函数没有原型
6.普通函数this指向调用者
▲ 7 简述常见异步编程方案 (promise, generator, async) 的原理
Promise 为我们解决了什么问题?在传统的异步编程中,如果异步之间存在依赖关系,就需要通过层层嵌套回调的方式满足
这种依赖,如果嵌套层数过多,可读性和可以维护性都会变得很差,产生所谓的“回调地狱”,而 Promise 将嵌套调用改为链
式调用,增加了可阅读性和可维护性。
▲ 6 简述 Javascript 的柯里化与逆柯里化
柯里化其实是函数式编程的一个过程,在这个过程中我们能把一个带有多个参数的函数转换成一系列的嵌套函数。它返回一个新函数,这个新函数期望传入下一个参数
优点: 可以轻松的重用和配置
避免调用相同参数的函数
▲ 6 简述常见的 HTTP 状态码的含义(301,304,401,403)
301:永久重定向
302:临时重定向
304:请求未修改
400:客户端错误
401:没有访问权,需要认证
403:服务端拒绝执行请求
404:请求资源未找到
▲ 4 数组去重有哪些方式?手写数组去重
set容器,对象key值方法,indexOf,for*2
▲ 4 Vue 组件间是如何进行通信的?
1.父子组件
父-子 props 子-父emit 2.vuex state,mutation,actions,getters modules 3.祖孙组件 provide和inject 允许祖先组件向子孙后代注入一个依赖,不论层次有多深,只要能够构成上下游的关系 缺点:当多个后代组件同时依赖同一个父组件提供数据时,只要任一组件对数据进行了修改,所有依赖的组件都会 受到影响,实际上是增加了耦合度。 任意层级访问使数据追踪变的比较困难,你并不能准确的定位到是哪一个层级对数据进行了改变,当数据出现问题时,尤其 是多人协作时,可能会大大增加问题定位的损耗。 4.eventBus:全局事件总线 Vue.prototype.EventBus = new Vue() vue的原型上挂载一个new Vue()
发送事件:this.emit()
接收事件:off()

    缺点:单页面程序刷新会移除所有的eventbus,当前的业务可能会断裂,所以切记在页面销毁的时候移除
    原理:它的工作原理是发布/订阅方法,通常称为 Pub/Sub 。两个方法$on和$emit。一个用于创建发出的事件,它就是$emit;另一个用于订阅$on:

▲ 2 CSS3 有哪些新特性
边框圆角,边框图片,flex布局,伪类,渐变背景,动画
▲ 2 CSS 的 position 常用值有哪些,有什么区别?
relative
absolute
static
fixed
inherit
▲ 1 CSS3 如何实现渐变色?
background-image: linear-gradient(angle, color-stop1, color-stop2);
background-image: radial-gradient(shape size at position, start-color, ..., last-color);
▲ 1 flex 常用的属性有哪些?flex: 1 1 0 是什么意思?
父元素{
flex-flow:
flex-direction:row,row-reverse,cloumn,cloumn-reverse
flex-wrap : wrap , nowrap , wrap-reverse
jusitfy-content : flex-start,flex-end,center,
space-betwwen(两边没有空隙),space-around(两边有空隙)
align-items:flex-start,flex-end,center,baseline,stretch
align-content(控制多行在竖直方向上的对齐方式,只有一行的话不会起作用):
flex-start,flex-end,center,stretch,space-between,space-around
}
子元素{
order:
flex{
flex-grow:0,有剩余空间,按照各个值的比例分配剩余空间
flex-shirk:1 没有剩余空间,所有item都会缩小,设置缩小的比例,0表示不缩小,不能为负值
flex-basis:auto,对item设置特定的宽高,
}
align-self: 某一个item竖直方向上的对齐方式,
}
▲ 1 如何实现 div 元素水平垂直居中
1.flex布局
2.子绝父相,letf50% margin-1/2width(tansform:translate(-50%,50%)
3..........四边0
▲ 1 什么情况下 z-index 不生效?
只有定位的元素(即position属性值不是static的元素)的z-index才会起作用。
▲ 8 简述 Javascript 的数据类型
原始值:String Boolean Number null undefined
引用值:Array Object Function
▲ 7 简述 webpack 的打包流程
webpack是模块打包器,主要是分析各个模块的的依赖关系,把复杂的文件依赖打包成单独的文件,并且可以把高级语法转化成浏览器可以识别的语法
1、安装babel的一系列插件
2、函数1:读取文件信息,并获取当前js文件的依赖关系:会返回下面的数据结构,这里包括了模块的id,文件路径,依赖数组(entry.js依赖了message.js,所以会返回依赖的文件名)
3、函数2:从入口开始分析所有的依赖,形成依赖图,采用广度遍历:遍历函数的依赖文件数组
4、函数3:根据生成的依赖关系图,生成浏览器可以执行的文件:处理模块关系数组,

▲ 6 简述 CSS 盒模型
标准盒模型:margin border padding content(width只有content)
IE盒模型:width包括 border + padding + content
可以通过box-sizing:border-box(IE)
content-box(默认)
▲ 4 rem 与 em 的区别以及使用场景
谷歌浏览器默认最小的font-size是12px,低于12的默认展示12px
em:首先会依据当前元素的font-size为基准,无论单位是什么,只要有fontsize属性,如果没有则相对于父元素的单位。
rem:会根据根元素为标准(html默认fontsize为16px)
▲ 3 const, let, var 关键字有什么区别?
1、变量提升
2.作用域,暂时性死区
3.const定义变量的地址不能被修改
▲ 9 readyState 的不同返回值有什么区别?
0:表示未初始化,1表示服务器连接已经建立,2表示正在发送请求,3表示正在处理请求,4表示请求结束完成响应
let xhr = new XMLHttpRequest
xhr.open(httpMethos,url,isAsync)
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200)
m = xhr.responseText
}
xhr.send()
▲ 2 实现三栏布局
1、float布局:左侧左浮动,右侧右浮动,中间margin左右
2、position布局:左侧left0,右侧right0,中间left左宽,right右宽
3、flex布局
▲ 1 正则表达式 /w 是什么意思?
看看
▲ 1 什么是可继承元素和不可继承元素?
font,font-size,color,text-align,line-height,font-family,

**extTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用
$nextTick,则可以在回调中获取更新后的 DOM
computed和methods
执行结果相同
computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值
method ,只要发生重新渲染,method 调用总会执行该函数
keep-alive

include:字符串或者正则表达式,匹配成功的会被缓存
exclude:字符串或者正则表达式,匹配成功的不会被缓存
是vue内置的一个组件,可以使被包含的组件保留状态或是避免重新渲染

for循环的key
主要用在vue的虚拟Dom算法上,用于识别新旧节点, 当数据变化后,可以最大程度的识别新增或者减少的节点,实现高效的更新
·····································································
BFC的理解,
display:inline-block
float
overflow:!visiable
position:absolute、fixed

选择器,层级上下文,
自适应布局rem原理(如何兼容不同手机dpi),
font-size 10px如何实现、
缩放
移动端一像素
旋转
媒体查询

js为什么需要放在body(更好的回答其实是浏览器的渲染引擎和js解析引擎的冲突,当然回答js是单线程执行也没问题,如何优化)?
操作DOM为什么是昂贵的?
操作dom,会出发页面进行重绘和重排,这些操作会严重影响浏览器的渲染性能,
优秀的框架:vue的虚拟dom和diff算法
事件委托

oop编程?
oop:面向对象编程(计算机编程架构):三大基本特性:封装,继承,多态
注重对象,当解决一个问题的时候,面向对象会把事物抽象成对象的概念,就是说这个问题里面有哪些对象,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,问题得到解决。
面向过程:注重过程的。当解决一个问题的时候,面向过程会把事情拆分成: 一个个函数和数据(用于方法的参数) 。然后按照一定的顺序,执行完这些方法(每个方法看作一个过程),等方法执行完了,事情就搞定了。

js深拷贝?(JSON方法实现拷贝有什么问题?)
1、原生递归方式:deepClone
2、JSON转换,不能对函数和一些特殊的对象进行处理
3、Object.assign(),只能对一级进行克隆,二级不会克隆,Object.assign({},target)
————————————————————————————————————————————————————————————————————————
数组乱序-洗牌算法
1、洗牌算法:从数组末位置开始计算,找到一个随机的位置进行位置互换,循环操作
2、sort(function(){ return .5-Math.random()}) a-b>0升序,反之降序 不同浏览器的js引擎对sort方法实现算法不一样,有冒泡,快排,插入排序
手动实现instanceof
function _instanceof(L,R){
let _R = R.prototype
while(true){
L = L.proto
if(L === null){
return false
}
if(L === _R){
return true
}
}
}

vue路由守卫
全局:beforeEach,beforeResolve,afterEach
路由独享:beforeEnter
组件:beforeRouteEnter、beforeRouteUpdate (2.2+)、beforeRouteLeave三个
vuex 和 全局变量的区别
1、响应式
2、修改状态的方式
3、命名冲突


node常用模块
http:用来创建服务器
path:常用来处理文件路径,通过path上的api可以路径信息上的参数,除此之外也有很多方法来解决实际遇到的问题,拼接和容错处理
fs:处理文件,对文文件进行读取和操作
url:对地址进行操作
events:对事件进行处理,监听,移除 发出等操作

webpack中loder和plugin区别
loader 用于加载某些资源文件。 因为webpack 本身只能打包commonjs规范的js文件,对于其他资源例如 css,图片,或者其他的语法集,比如 jsx, coffee,是没有办法加载的。 这就需要对应的loader将资源转化,加载进来。从字面意思也能看出,loader是用于加载的,它作用于一个个文件上。

对于plugin,它就是一个扩展器,它丰富了wepack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件内容,而是基于事件机制工作,会监听webpack打包过程中的某些节点

面试题:
webpack中常用的loader和plugin
判断对象或者是数组
判断是一个空对象
两个字符串的最短相同子串

didi

css选择第二个a标签 (元素,类,id,属性,派生) li:nth-child(3){background:#090} nth-last-of-type() 作用类似,但是仅匹配使用同种标签的元素 input[type="text"]
bfc: display float overflow position
设计一个抽奖系统
typeof instanceof(一个对象的原型链上是否存在另一个对象的原型) 返回值不一样,
diff
数组扁平化 reduce递归 循环递归 while三点运算符 Array.flat
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
手写promise
js单线程? 作为浏览器脚本语言,JavaScript 的主要用途是与用户互动,以及操作 DOM。这决定了它只能是单线程,
观察者模式
saas

二叉树

冒泡,排序的算法
webpack相关
vue的filters
动态规划
字符串模板的方法

你可能感兴趣的:(面试)