JavaScript 基础

一. event loop 事件循环

JavaScript 是一门单线程语言,它的异步是通过 event loop 实现的。

  1. 大致有三部分组成 执行栈 宏任务队列 微任务队列
  2. event loop 开始会从全局代码开始执行,一行一行执行,遇到函数调用时,会把代码压入到 执行栈
  3. 遇到 setTimeout, setInterval,异步回调等 会进入 宏任务队列,等 执行栈 为空后执行
  4. 遇到 promise,async,await 等 会进入 微任务队列 当中,等 执行栈 为空后立即执行
  5. 微任务队列宏任务队列 优先等级高,所以 执行栈 为空后,先执行 微任务队列 再执行 宏任务队列

二. js数据类型

数据类型有 null,undefined,string,number,object,Boolean,Symbol object 是复杂数据类型(引用数据类型),其余都是普通数据类型

三. var let const的区别

var 函数作用域,支持变量提升,允许重复声明。 let 块级作用域,不支持变量提升,不允许重复声明,暂存性死区。不能通过window.变量名进行访问。 const 块级作用域,不支持变量提升,不允许重复声明,暂存性死区。声明一个变量一旦声明就不能改变,改变报错。

四.web储存 cookie,sessionStorage,localStorage

名称大小服务端通信过期时间清除
cookie4k左右始终在同源的http请求中携带在设置过期时间之前都有效设置过期时间
sessionStorage5M左右不会自动把数据发给服务器不可设置过期时间,当前浏览器窗口有效关闭浏览器会清除
localStorage5M左右不会自动把数据发给服务器不可设置过期时间,可长期保存手动清除

五.事件冒泡与事件捕捉

事件捕获: 就是从根元素开始向目标元素递进的一个关系;从上而下。 事件冒泡:是从目标元素开始向根元素冒泡的过程; 从下而上。

六. 说一下 vue 的生命周期

从vue实例创建,运行,到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期 生命周期钩子,就是生命周期事件的别名。 8个钩子函数 beforeCreate 创建之前 created 创建完成 beforeMount 挂载之前 mounted 挂载完成 beforeUpdate 更新之前 updated 更新完成 beforeDestroy 销毁之前 destroyed 销毁完成

created 实例创建完成,可获取data 可获取方法,实例已经初始化,还没有挂载 到 $el 上无法获取节点。可进行数据的获取。

mounted 已经挂载到 $el 上,页面已经显示在浏览器中,可以调用节点。比如: 使用插件chart.js

七. 简述 MVVM 模式

MVVM是Model – View – ViewModel 的缩写 Model 代表数据模型 View 代表 UI组件 ViewModel 同步View和model的对象,连接Model和View

八. 闭包

闭包: 指有权访问另一个函数作用域中变量的函数 函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包 闭包的作用: 延伸了变量的作用范围 缺点: 函数变量会保存到内存中,内存消耗大。

九. 垃圾回收

js拥有特殊的垃圾回收机制,当一个变量在内存中失去引用,js会通过特殊的算法将其回收,并释放内存。 两个阶段 1.标记阶段 2.清除阶段

十. 浅拷贝与深拷贝

浅拷贝 通常需要拷贝的对象内部只有一层的这种对象,更深层次对象级别的只拷贝引用。 Object.assign 实现

深拷贝 通常是嵌套二层或以上的复杂对象 JSON.parse(JSON.stringify(object)); 该方法忽略 undefined, function, Symbol, 只适合简单深拷贝 使用函数递归实现复杂深拷贝

十一. 函数的节流和防抖

节流: 将多次执行变成每隔一个时间节点去执行; 防抖: 将多次触发变成最后一次触发;

十二. call、apply、bind的区别

相同点: 改变this的指向 不同点: call与bind 第二个参数是若干个参数列表,apply 是数组。 call与apply 是会进行函数的调用,bind不会进行函数的调用。 call与apply 改变函数,bind是生成一个改变后的新函数。

十三. 普通函数this 与箭头函数 this 的区别

普通函数总是指向它的调用者,普通模式下,没有找到直接调用者,this指向window,严格模式下 this 是 undefined,使用call,apply,bind可改变this的指向。 箭头函数指向定义时所在对象,而不是使用时所在对象。不能用做构造函数。

十四. 性能优化的方法

  1. dns 预解析
  2. 浏览器缓存
  3. 预加载
  4. 预渲染
  5. 懒加载
  6. 文件优化

十五. async / await

使用 async/ await 结合 promise ,编写形似同步代码来处理异步流程,使代码更简洁,可读性更高。async声明一个函数是异步的,await 等待异步函数执行完成。

十六. promise

promise 是异步编程的解决办法,比传统的回调函数/事件更强大。它有三个状态,分别是 pending - 进行中,resolved - 已完成,rejected - 已失败。

十七. 讲一下原型与原型链

原型是一个对象,也可以称 prototype为原型对象。原型对象的作用: 共享方法。 原型链 实例化构造函数后得到一个对象,对象里面有一个 proto 指向构造函数的原型对象 prototype 构造函数的原型对象prototype里面也有一个 proto(对象原型),它指向的是 Object.prototype(原型对象) Object.prototype 里面也有一个 proto(对象原型),它指向的是 null

十八. 虚拟 DOM 与真实 DOM 的区别

  1. 虚拟 DOM 进行频繁修改,然后一次性比较并修改真实 DOM 中需要修改的部分,最后并在真实 DOM 中进行排版与重绘,减少过多的 DOM 节点排版与重绘损耗。
  2. 真实DOM频繁排版与重绘的效率是相当低的。
  3. 虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部。

十九. 解决跨域都哪些方法

  1. jsonp 通过 script 标签可以访问其他域的函数,不受浏览器同源策略的限制。
  2. href 与 src href 是超文本引用,使用场景 a 和 link 引用时不会影响页面的继续加载。引用css时会同步加载css内容。 src 是对资源的引用,它指向的内容会嵌入到当前标签所在位置,页面会停止加载,等引用资源加载完成,再继续加载当前页面内容。使用场景 img,iframe,script

二十.vue组件之间的传值

  1. 父组件通过 props 向子组件传递
  2. 子组件通过 $emit 事件触发的形式向父组件传递
  3. 兄弟组件之前通过定义 公用实例文件 bus.js , 作为中间仓库来传值
  4. 项目组件过多使用 vuex

二十一.说一下 vuex

vuex是vue中的一个状态管理模式

五个属性

  1. state vuex的基本数据,用来储存变量。
  2. getter 从基本数据(state)派生的数据,相当于state的计算属性。
  3. mutation 同步修改基本数据(state)
  4. action 异步修改基本数据(state)
  5. modules 模块

二十二. vue 双向绑定

vue的双向绑定是通过数据劫持的方式结合订阅者-发布者模式实现的。 具体点就是通过 Object.definedProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

二十三. vue 计算属性的用法

在一个计算属性里可以完成各种复杂的逻辑,包括运算,函数调用等,最终返回一个结果就可以。计算属性是基于它们的依赖进行缓存的

二十四. vue 有哪些跳转方式 # 有什么区别

四种跳转方式

  1. router-link
  2. this.$router.push()
  3. this.$router.replace()
  4. this.$router.go() this.$router.push 跳转到某个页面,并向 history栈中添加一个记录,点击后退会返回上一个页面。 this.$router.replace 跳转到某个页面,不会向 history 栈中添加记录,点击后退会返回上上个页面。 this.$router.go(n) 向前或向后跳转 n 个页面,n可以是正整数或者负整数。

二十五. vue 的 keep-alive的作用

keep-alive 是vue的内置组件,是用来缓存组件的,避免多次加载相同的组件,增加性能消耗,如果频繁切换组件就需要keep-alive

  1. include 字符串或者正则表达式,只有名称匹配的才会被缓存。
  2. exclude 字符串或者正则表达式,任何名称匹配的都不会被缓存。
  3. max 设置最大缓存多少组件。