知识点:面试自我总结5.17

228 阅读13分钟

谈谈this的指向

谁调用指向谁,只有函数在调用的时候才能确定this的指向 普通函数 直接调用,指向window 对象调用,指向对像 Call/apply调用,指向传入的第一个参数 New调用,指向生成实例对象 回调函数 定时器回调函数,指向window DOM事件回调函数,,指向绑定事件的DOM元素 Vue普通事件回调函数,生命周期函数,指向组件实例对象 箭头函数 没有自己的this,跟外层函数的this一致

谈谈箭头函数

箭头函数没有自己的this,也没有自己的arguments,跟外层函数的this和argument一致,如果没有外层,那么久报错 Arguments是实参列表,只要传入实参,就可以在函数内部通过arguments获取 箭头函数没有显示原型属性,不能被new调用 箭头函数有隐式原型属性,可以使用call/apply,但是没有意义,因为没有自己的this,改变不了指向 箭头函数还可以简写,一个参数可以()不写,一条语句,可以{}不写,{}如果不写,就会把这条语句的返回值return出去 箭头函数使用的地方:如果你想使用外部的this,就可以使用箭头函数

谈谈call/apply/bind 三者的联系和区别

Call和apply,都可以改变this的指向 但是call传入的参数可以有N个,第一个就是改变this的指向,第二个开始就是实参 Apply传入的参数只有2个,第一个就是改变this的指向,第二个是数组,数组内的值作为函数的实参 Bind bind 方法调用返回值是一个新函数,新函数的 this 才会变化,原函数不变 bind 不会立即调用原函数

谈谈ES5

1.严格模式

让代码在更严格的环境下运行,减少错误,this指向undefined,通常 webpack 中 babel 工具会自动加,不用担心

2.对象的扩展方法

Object.defineProperty() 在 Vue 双向数据绑定原理中,Vue 响应式原理中都有出现

3.数组的扩展方法

ForEach 不会产生新数组,返回undefined ,循环全部

Filter 返回的是一个新数组,原数组不会变化.过滤的是满足条件的成员,然后组成新数组返回,使用return操作输出,会循环数组每一项,并在回调函数中操作

Map 返回的是一个新数组,原数组不会变化,使用return操作输出,会循环数组每一项,并在回调函数中操作

----由于map、filter的返回值是数组,因此也可以链式使用

Find 不创建新数组,不改变原数组,只要找到为true,就跳出循环,不再查看下面的 使用return操作输出,会循环数组每一项,并在回调函数中操作

Reduce 依次处理数组的成员,最终累计为一个值 (比如求和、求积);

4.函数的扩展方法

Bind 在 React 中,定义组件类修改函数 this 指向

谈谈ES6

像解构赋值、三点运算符、模板字符串、let/const 关键字,symbol 箭头函数&this 指向 异步编程解决方案 问题:回调地狱问题 解决:Promise / async,await(ES8)

谈谈promise

异步操作[AJAX,数据库处理,mongodb,文件读写fs]

Promise是异步编程的解决方案;能够通过链式调用,解决回调地狱[es6提出的新技术,旧的方案:单纯使用回调函数] 用在的场景,发送请求 Promise对象有3个状态:

  1. pending 初始化状态 创建promise对象的时候,默认为pending
  2. resolved 成功的状态 调用resolve函数,就会变成 成功的状态
  3. rejected 失败的状态 调用reject函数,就会变成 失败的状态

promise 的状态只能修改一次

.then,捕获promise成功/失败的状态,执行成功/失败的回调

.catch捕获promise失败的状态,执行失败的回调

方法:

Promise.all(),传入N个promise对象,只有全部成功,才成功,成功返回全部一个失败,那就失败,失败的返回 Promise.allSettled(),传入N个promise对象,等 n 个 promise 对象状态全部发生变化,得到所有结果值 Promise.resolve() 返回一个成功状态 promise 对象 Promise.reject() 返回一个失败状态 promise 对象

谈谈async/await

async 是解决异步编程最好用的方案,本质上是 generator 的语法糖

async 函数返回值是一个 promise 对象

await 右边是 promise 对象

成功可以直接把成功的值return出来,失败的话,可以用try{}catch{}

宏队列和微队列

1.宏队列:DOM事件回调,ajax回调,定时间回调 2.微队列:promise回调,mutation回调 先同步,再异步,异步,先清空微队列,再执行宏队列

谈谈ES7

** 指数运算

谈谈ES8

async/await

谈谈ES10

Bigint 因为number数比较大,精度会有错误,所以才有bigint 数据类型:string,boolean,number,null,undefined,symbol,bigint import() 动态导入--- 项目路由懒加载 数组的flat() 数组扁平化,将多维数组变成一维数组

谈谈ES11

Promise.allSettled([]) 不管状态变成成功和失败,都会返回一个成功的promise,结果值包含所有promise对象的结果

Promise.all([]) 只有所有promise对象都成功,才成功,只要有一个失败就失败

谈谈作用域

作用域就是一段代码的地盘,他的主要作用就是隔离变量防止污染 作用域链,用来查找变量的,自身作用域找不到,就找上一级,直到全局作用域,再找不到就报错(xxx is not defined)

谈谈闭包

1.什么是闭包?

闭包是一个引用关系,该引用关系存在内部函数中,引用的是外部函数的变量的对象

closure 闭包存在嵌套的内部函数中,通过 chrome 调试查看

2.产生的条件

函数嵌套,内部函数引用外部函数的局部变量,执行外部函数 内部函数引用全局变量,不会产生闭包

3.闭包作用

延长外部函数变量的生命周期,让函数外部操作函数内部的数据

4.闭包的生命周期

产生:内部函数在定义完时就产生了(不是在调用) 死亡:在内部函数成为垃圾对象时

5.闭包缺点

容易导致内存泄漏 内存泄漏:内存无法释放 内存溢出:内存被撑爆(程序会直接崩溃) 解决:及时释放--让内部函数成为垃圾对象 fn = null;

6.闭包应用:

高阶函数(执行函数返回值新函数) --> React 框架/库底层源码 --> Vue

谈谈原型

1.什么是原型?

原型指的就是原型对象, 原型对象有两个原型属性:prototype显示原型属性 和 __proto__隐式原型属性 Prototype(显示原型属性)是函数对象身上的一个属性 proto(隐式原型属性)是函数实例化对象身上的一个属性,它和函数对象prototype(显示原型属性)地址一样,代表同一个对象(原型对象).

知识点:
  • 函数对象的显示原型对象 === 实例化对象的隐式原型对象
  • 函数对象的prototype,我们通常是通过它写这个对象的
  • 实例化对象的__proto__,我们通常是通过它来读这个对象的
  • 原型对象身上也有一个constructor[构造器],值就是函数本身
  • 原型对象默认是Object的实例化对象,
  • 箭头函数没有显示原型属性!!!
  • 所有对象都有隐私原型

2.原型的作用:通过继承的方式,来复用代码(共享资源,节约代码)

特殊:Object.prototype.proto === null

3.谈谈原型链

由多个proto(隐式原型属性)组成结构就是原型链 作用:用来找属性和方法的

谈谈axios

前端最流行的 ajax 请求库,基于 promise 的异步 ajax 请求库,支持promise所有的API 在axios,有封装过请求拦截,然后又一条痕迹的,还有

谈谈webpack

Webpack是一个模块打包工具,主要有5个核心概念

  • Entry 入口
    指示 webpack 从哪个文件开始构建/打包
  • Output 出口
    指示 webpack 打包完成的文件输出哪里去
  • Loader 加载器
  1. webpack 自身能力有限,只能处理 js/json 文件,但是遇到 css/html 等文件就没办法处理;
  2. loader 能将 webpack 不识别的文件编译加载成 webpack 能识别的文件,这样才能打包处理
  • plugin插件
    功能比 loader 更加强大,增强 webpack 的功能 html-webpack-plugin
  • Mode模式
  1. Develpment开发环境
  2. Production生成环境
优化:

1.去除无用的js代码 ---tree shaking 树摇优化

比如引入工具函数库(lodush),里面有好多工具函数,开发用的就其中几个,然后还有好多工具函数没用,最终打包就有好多没用的代码,树摇就会去除没用的代码

  • 使用树摇的前提:
  1. 必须使用 ES6 模块化
  2. 开启 production 生产环境模式 -自动激活
2.优化: 兼容性处理

1.使用babel-loader,把ES6的简单转换为ES5的语法,复杂(promise,async)转换不了

2.使用core-js -按需加载兼容性包

谈谈cookie,storage的区别

存储大小: Cookie 4K , storage5M

有效期:

  1. Cookie 拥有有效期,发送到服务器端,存在内存中
  2. Localstorage:永久存储,存在浏览器端
  3. Sessionstorage:会话技术,存在内存,关闭网站就没了

路径: cookie有路径限制,storage只存在域名下

API:cookie没有特点API,storage有对应的API

谈谈防抖节流

  • 防抖:多次事件触发,只执行一次 ---搜索框 当用户在input标签里疯狂输入值,而此同时我们只打算取最后一次输入的值
  • 节流:事件触发,固定时间内执行一次 向下滑动请求后台接口,且滑动十分频繁。

谈谈Vue的知识点

Vue.nextTick 在下次DOM更新循环结束之后执行延迟回调 --在swpier有用到过

Vue.directive 注册全局指令

data,为什么要定义为函数,如果把组件重复调用了3次的话,那么我其中一个组件的数据发生变化,那其他组件也会发生变化定义为函数,每次就会产生新数组,就互不影响

1.生命周期

Vue的生命周期有10个,2个不常用 1.BeforeCreate[创建前] el与data还未初始化还不能访问data、computed、watch、methods 上的方法和数据.[全局事件总线就在这里用的]

知识: vue的数据代理和数据劫持,在becreate 和created之间, 在 created打印的话, 就能看到了

2.Create[创建后] 当前生命周期data初始化完成,可以访问到data、computed、watch、 methods上的方法和数据,el初始化还没完成所以还不能访问

知识:可以做前后端的交互, 例:异步请求如ajax

3.Beforemount[挂载前] 当前生命周期在挂载开始之前被调用, 挂载元素, 获取到DOM节点(但数据和模板还未结合)

4.Mountde[挂载后] 当前生命周期el已经挂载到文档里
可以操作DOM节点 (数据和模板成功渲染)

5.beforeUpdate[更新前] 当前生命周期在数据更新的时候就会执行 更新的data数据和模 板还没结合,可以在当前生命周期做一个数据的最后修改

6.Updated[更新后] 当前生命周期更新的数据与模板结合完毕 可以做一个确认停止事 件的确认框

7.beforeDestroy(销毁前-常用) 实例销毁之前调用 当前生命周期做一些移除的操作。

例:监听的移除,定时器的移除,事件的解绑

8.destroy(销毁后) 当前生命周期数据与视图之间的关系将会断开

9.activated A--->B B就activated A就deactivated

10.deactivated keep-alive缓存组件的时候激活调用

父子组件的生命周期中,首先走父组件的生命周期,当父组件的生命周期走完beforeMount(挂在前)这个函数时就会走子组件的生命周期,当子组件挂载完成后(执行完mounted)父组件再继续走

2.vue组件间通信 10个

父子

  1. props
  2. vue自定义事件
  3. v-model
  4. .sync
  5. 插槽 ==> 作用域插槽
  6. attrsattrs与listeners
  7. ref,ref, children与$parent

祖孙

  1. provide与inject

任意

  1. Vuex
  2. 全局事件总线

3.谈谈vueX

Vuex是一个集中管理状态数据的工具

主要有5个对象

  • State 管理状态数据 在组件中想要获取状态数据:$store.state.状态数据

  • Mutations 直接修改状态数据 如果想要在组件中找某个mutation,那么用$store对 象.commit('某个mutation')

  • Actions 间接修改状态数据 如果想要在组件中找某个action,那么用$store对 象.dispatch('某个action')

  • Getters 状态数据的计算属性

  • modules 模块

4.谈谈vueRouter

Vuerouter是路由管理器

5.谈谈响应式原理

当数据发生变化,数据变,页面也变

1.数据代理是干嘛的?将data数据代理到this上(方便后面操作data数据) 遍历data中所有数据,通过Object.defineProperty()方法 ,将data中的数据定义在this上;然后在方法里面就通过get,set设置和读取原数据的值

2.数据劫持是干嘛的?将data数据重新定义,将其定义成响应式 遍历data中所有数据,通过Object.defineProperty()方法,重新定义属性get和set 然后用闭包的方式保存了一个dep对象 get中将来通过dep就能建立dep和watcher的联系 set中将来通过dep就能通知所有watcher去更新用户界面

3.模板解析 将指令语法/插值语法 编译解析 watcher是在模板解析才有的 将元素节点转换成文档碎片节点,然后编译模板,然后再把编译后的模板添加到(el元素中)页面中生效 主要就在解析模板 取出所有子节点,进行遍历 判断节点是元素节点还是文本节点 nodetype 如果是文本节点,要编译插值语法,最终会给元素设置textContext,值为表达式对应的值 如果是是元素节点,要编译指令语法 当前元素所有属性,判断属性是不是指令属性 判断是事件指令 v-on 给元素绑定事件,同时回调函数会通过bind方法强制改变this指向为vm 判断是普通指令 就会相应的解析 最终会new Watcher(),new Watcher时就会建立起dep和watcher的联系

6.谈谈双向数据绑定

双向数据绑定原理,是通过v-model来实现双向数据绑定原理 v-model会给元素绑定value属性(数据就从数据Model流向页面View),和绑定input事件 当用户输入数据,会触发input事件,在input事件中会更新data数据(数据就从页面View流向数据Model)

谈谈MVVM和MVC

MVVM是Model-View-ViewModel的缩写,是一种设计思想。 Model层代表数据模型 View层代界面 ViewModel是一个同步View和Model的对象 在MVVM的架构下,View和Model之间并没有直接联系,而是通过ViewModel进行交互的 Model和ViewModel之间的交互是双向,因此,View数据变化会同步到Model中,而Model数据变化会立即反应到View中

说一下MVVM和MVC的区别 MVVM和MVC其实区别并不大,都是一种设计思想。主要是MVC中Controller演变成mvvm中的viewmodel。 MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验。