前端面试(2)

文章目录

    • 51.构造渲染树的流程
    • 52.什么是不可见节点
    • 53.什么是promise,用来做什么
    • 54.promise.all
    • 55.事件轮询
    • 56.JavaScript为什么是单线程的,不能实现多线程吗
    • 57.promise的常用静态方法
    • 58.promise的实例方法
    • 59.ES6
    • 60.判断空对象的几种方式
    • 61.Proxy和defineProperty的区别。
          • Object.defineProperty和Proxy的区别
      • Proxy的优势如下:
      • Object.defineProperty如下:
    • 62.装饰器
    • 63.Vue3 与 Vue2 区别详述
      • 1.生命周期
      • 2.多根节点
      • 3.APi
      • 4.异步组件
      • 5.响应式原理
      • 6.diff算法优化
    • 64.computed计算属性
    • 65.computed,watch,method的区别?
    • 66.Vue中的 computed 和 watch的区别
    • 67.vue中的token存储
    • 68.vuex
    • 69.vuex的5个核心属性
    • 70.vuex中的状态存储在哪里,怎么改变他
    • 71.vuex中的状态是对象的时候,需要注意什么
    • 72.在Vuex的state中有个状态number表示货物数量,在组件怎么改变它。
    • 73.在v-model上怎么用Vuex中state的值?
    • 74.Vuex中action和mutation
    • 75.vue中的key值
    • 76.keep-alive
    • 77.常用的钩子函数
        • beforeCreate
        • created
        • mounted
        • computed
        • watch
    • 78.route和router
    • 79.为什么v-for一定要绑定key
    • 80.路由守卫
    • 81.路由器的两种工作模式
    • 82.返回上一级路由
    • 83.依赖收集
    • 84.nexttick实现原理
    • 85.vue组件之间的六种通信方式
      • 父组件向子组件传值 props
      • 子组件向父组件传值(通过事件形式) $emit
      • 事件总线
    • vuex
    • 86.vue中组件和插件的区别
    • 87.vue中的diff算法
    • 88.声明周期和执行顺序
      • 数据请求放在哪
    • 89.虚拟DOM为什么会比真实DOM快
    • 90.typeof判断null和undifined的区别
    • 91.常见的类数组
    • 92.v-module指令的修饰符
    • 93.Vue v-pre、v-once 指令
    • 94.垃圾回收机制(GC机制)
    • 95.ajax跨域解决
    • 96.vue的设计模式
    • 97.动画
    • 98.为什么usestate使用数组不使用对象(react)
    • 99.高阶函数和高阶组件的区别(react)
    • 100.组件传值组件通信的方案(react)
    • 为什么react里没有vue中的声明周期什么的

51.构造渲染树的流程

  • 从 DOM 树的根节点开始遍历每个可见节点。
  • 对于每个可见的节点,找到 CSSOM 树中对应的规则,并应用它们。
  • 根据每个可见节点以及其对应的样式,组合生成渲染树。

52.什么是不可见节点

一些不会渲染输出的节点,比如 script、meta、link 等。

一些通过 css 进行隐藏的节点。比如 display : none。注意,使用 visibility 和 opacity 隐藏的节点,还是会显示在渲染树上的(因为还占据文档空间),只有 display : none 的节点才不会显示在渲染树上

53.什么是promise,用来做什么

Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

promise是用来解决两个问题的:

  • 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
  • promise可以支持多个并发的请求,获取并发请求中的数据
  • 这个promise可以解决异步的问题,本身不能说promise是异步的

54.promise.all

用于将多个 Promise 实例,包装成一个新的 Promise 实例。该方法提供了并行执行异步操作的能力,并且在所有异步操作执行完并且执行结果都是成功的时候才执行回调。

  1. Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用Promise.resolve方法将参数转为 Promise 实例再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

  2. p的状态怎么决定?

    2.1.只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数 组,传递给p的回调函数。
    ​ 2.2.只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

注意: 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法,若被rejected的 Promise 实例没有自己的catch方法,就会调用Promise.all()的catch方法。

55.事件轮询

js是单线程的,执行较长的js时候,页面会卡死,无法响应,但是所有的操作都会被记住到另外的队列。比如:点击了一个元素,不会立刻的执行,但是等到js加载完毕后就会执行刚才点击的操作,能够知道有一个队列记录了所有有待执行的操作,这个队列分为微观和宏观。微观会比宏观执行得更快。

event loop它最主要是分三部分:主线程、宏队列(macrotask)、微队列(microtask) js的任务队列分为同步任务和异步任务,所有的同步任务都是在主线程里执行的,异步任务可能会在macrotask或者microtask里面。

事件循环就是多线程的一种工作方式,Chrome里面是使用了共享的task_runner对象给自己和其它线程post task过来存起来,用一个死循环不断地取出task执行,或者进入休眠等待被唤醒。Mac的Chrome渲染线程和浏览器线程还借助了Mac的sdk Cococa的NSRunLoop来做为UI事件的消息源。Chrome的多进程通信(不同进程的IO线程的本地socket通信)借助了libevent的事件循环,并加入了到了主消息循环里面。

56.JavaScript为什么是单线程的,不能实现多线程吗

JavaScript单线程是指浏览器在解释和执行javascript代码时只有一个线程,即JS引擎线程,浏览器自身还会提供其他线程来支持这些异步方法,浏览器的渲染线程大概有一下几种:

JS引擎线程 事件触发线程 定时触发器线程 异步http请求线程 GUI渲染线程 …

event loop就是解决这个问题的

57.promise的常用静态方法

promise.all

所有可迭代的Promise都通过则认为是成功,如果有一个拒绝,则认为失败。

** 图片批量上传 **

promise.race

每次执行,无论成功还是失败,其输出的信息中的时间一定是延时时间最短的那个。

** 请求可以在200ms内完成,则不显示loading,如果要超过200ms,则至少显示200ms的loading。 **

promise.any

只要有一个成功就可以了,除非所有的Promise都拒绝,否则就认为成功。

** 通过不同路径请求同一个资源的需求上 **

promise.resolve

返回给定值解析后的promise对象,

  • 如果这个值是一个 promise ,那么将返回这个 promise

  • 参数不是具有then()方法的对象,或根本就不是对象,Promise.resolve()会返回一个新的 Promise 对象,状态为resolved

  • 没有参数时,直接返回一个resolved状态的 Promise 对象

58.promise的实例方法

then()

catch()

finally()

59.ES6

let,const

模板字符串

箭头函数

函数的参数默认值

…运算符

对象和数组的解构

对象超类

for…of 和for … in

class

60.判断空对象的几种方式

  1. 将json对象转化为json字符串,再判断该字符串是否为"{}"
  2. for in 循环判断
  3. jquery的isEmptyObject方法
  4. Object.getOwnPropertyNames()方法
  5. 使用ES6的Object.keys()方法

61.Proxy和defineProperty的区别。

Proxy是ES6推出的一个类,给对象架设一层拦截器,但凡要访问或者修改这个对象上的值或者属性,都必须先经过这层拦截器, Proxy也叫代理器, 它代理了对对象的操作。

Object.definePrototype是对对象上的属性进行新增或者修改, 有2种写法,数据描述符或者访问器描述符, IE8不支持(敲黑板, 面试官再问起来为什么Vue不支持IE8,就这么告诉他)

Object.defineProperty和Proxy的区别
  • Object.defineProperty对对象自身做修改, 而Proxy只是在Object基础上加一层拦截,不修改原对象(其实并不是这样,对于不支持嵌套对象,如果你想监听嵌套的,那么这个地方就不对了。后面会说到)
  • 监听不了数组的变化
  • 监听手段比较单一,只能监听set和get, Proxy有10几种监听
  • 必须得把所有的属性全部添加defineProperty, Proxy对整个对象都会进行拦截

Proxy的优势如下:

  • Proxy可以直接监听对象而非属性;
  • Proxy可以直接监听数组的变化;
  • Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的;
  • Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改;
  • Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

Object.defineProperty如下:

  • 兼容性好(支持IE9)

Object.defineProperty (obj, prop, descriptor) 的问题主要有三个:

  • 无法监听数组的变化
    Vue 把会修改原来数组的方法定义为变异方法。
    变异方法例如 push、pop、shift、unshift、splice、sort、reverse等,是无法触发 set 的。
    非变异方法,例如 filter,concat,slice 等,它们都不会修改原始数组,而会返回一个新的数组。
    Vue 的做法是把这些变异方法重写来实现监听数组变化。
  • 必须遍历对象的每个属性
    使用 Object.defineProperty 多数情况下要配合 Object.keys 和遍历,于是就多了一层嵌套。
    并且由于遍历的原因,假如对象上的某个属性并不需要“劫持”,但此时依然会对其添加“劫持”。
  • 必须深层遍历嵌套的对象
    当一个对象为深层嵌套的时候,必须进行逐层遍历,直到把每个对象的每个属性都调用 Object.defineProperty() 为止。

62.装饰器

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上

是一种在不改变原类和使用继承的情况下,动态地扩展对象功能

同样的,本质也不是什么高大上的结构,就是一个普通的函数,@expression 的形式其实是Object.defineProperty的语法糖

expression求值后必须也是一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入

代码可读性变强,装饰器命名相当于一个注释,在不改变原来代码的情况下,对原来的功能进行扩展

63.Vue3 与 Vue2 区别详述

1.生命周期

整体上变化不大,只是大部分生命周期钩子名称上 + “on”,功能上是类似的。不过有一点需要注意,Vue3 在组合式API(Composition API,下面展开)中使用生命周期钩子时需要先引入,而 Vue2 在选项API(Options API)中可以直接调用生命周期钩子,如下所示。

2.多根节点

vue2使用多根节点会报错,vue3支持多根节点

3.APi

vue2是选项api,vue3是组合式api

4.异步组件

vue3提供异步组件,允许程序在等待异步组件加载完成前渲染兜底的内容

5.响应式原理

vue2响应式原理的基础是 Object.defineProperty;Vue3 响应式原理基础是 Proxy。

6.diff算法优化

64.computed计算属性

computed是一个计算属性,类似于过滤器,对绑定到view的数据进行处理,计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。它用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理。

  计算属性不是异步更新的。渲染的时候才能取到最新的值。

65.computed,watch,method的区别?

(1)method方法只要把方法用到模板上了,当每次一变化就会重新视图渲染,它的性能开销就比较大。computed计算属性也是一个watcher是具备缓存的,只有当依赖的属性发生变化时才会更新视图。

如果页面中有属性需求区计算不要在页面中这样写{{fn()}},这时候可以写一个计算属性,渲染的时候它依赖的属性没有发生变化,它就不会导致方法重新执行。

(2)computed和watch的原理它们里面都是一个watcher来实现的,computed是具备缓存的,watch不具备。

66.Vue中的 computed 和 watch的区别

computed看上去是方法,但是实际上是计算属性,它会根据你所依赖的数据动态显示新的计算结果。计算结果会被缓存,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算

watcher 更像是一个 data 的数据监听回调,当依赖的 data 的数据变化,执行回调,在方法中会传入 newVal 和 oldVal。可以提供输入值无效,提供中间值 特场景。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。如果你需要在某个数据变化时做一些事情,使用watch。

67.vue中的token存储

在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:

1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码

2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token

3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面

4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面

5、每次调后端接口,都要在请求头中加token

6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401

7、如果前端拿到状态码为401,就清除token信息并跳转到登录页面

68.vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态,而更改状态的唯一方法是提交mutation,例this.$store.commit('SET_VIDEO_PAUSE', video_pauseSET_VIDEO_PAUSE为mutations属性中定义的方法 。

69.vuex的5个核心属性

state、getters、mutations、actions、modules 。

70.vuex中的状态存储在哪里,怎么改变他

存储在state中,改变Vuex中的状态的唯一途径就是显式地提交 (commit) mutation。

71.vuex中的状态是对象的时候,需要注意什么

因为对象是引用类型,复制后改变属性还是会影响原始数据,这样会改变state里面的状态,是不允许,所以先用深度克隆复制对象,再修改。

72.在Vuex的state中有个状态number表示货物数量,在组件怎么改变它。

首先要在mutations中注册一个mutation

在组件中使用this.$store.commit提交mutation,改变number

73.在v-model上怎么用Vuex中state的值?

需要通过computed计算属性来转换

74.Vuex中action和mutation

action 提交的是 mutation,而不是直接变更状态。mutation可以直接变更状态。

action 可以包含任意异步操作。mutation只能是同步操作。

提交方式不同,action 是用this.$store.dispatch('ACTION_NAME',data)来提交。mutation是用this.$store.commit('SET_NUMBER',10)来提交。

75.vue中的key值

key就是一个标识,被使用在Vue中。再详细一点,key被使用在Vue中的虚拟DOM中,并不会出现在真实DOM中。

Vue的操作是,拿根据新的数据生成的【新的虚拟DOM】与之前的【真实的DOM】去做比较,如果相同,直接延用即可(“拿来主义”);如果不同,则生成新的DOM对象。

76.keep-alive

keep-alive 是 vue 内置的组件,用 keep-alive 包裹组件时,会缓存不活动的组件实例,而不是销毁他们。主要用于保存组件状态或避免重复创建避免重复渲染导致的性能问题

它是一个抽象组件,自身不会渲染一个 dom 元素,也不会出现在组件的父组件链中。

当组件在 keep-alive 内被切换,组件的 activated 和 deactivated 这两个生命周期钩子函数会被执行。组件一旦被 缓存,再次渲染就不会执行 created、mounted 生命周期钩子函数。

要求同时只有一个子组件被渲染。

不会在函数式组件中正常工作,因为它们没有缓存实例。

77.常用的钩子函数

beforeCreate

这个时候,this变量还不能使用,在data下的数据,和methods下的方法,watcher中的事件都不能获得到;

created

这个时候可以操作vue实例中的数据和各种方法,但是还不能对"dom"节点进行操作;

mounted

这个时候挂载完毕,这时dom节点被渲染到文档内,一些需要dom的操作在此时才能正常进行。

computed
watch

78.route和router

共同点 使用时都需要在前面加上$

不同点

可以从route里获取到路由信息,包括当前激活的路由地址,路由中的query参数

router的作用: 可以进行路由跳转,其中具体的方法有:

  • push() :相当于Html5中的history.pushState()方法,将当前路由压
  • replace() : 相当于Html5中的history.replace()方法,将当前路由替换.
  • go(): 相当于Html5中的history.go()方法,当参数为1时,前进一个.参数为-1时,后退一个.
  • back():相当于Html5中的history.back()方法,向后回退一个.
  • forward():相当于Html5中的history.forward()方法,向前前进一个.

79.为什么v-for一定要绑定key

当使用v-for递归虚拟DOM发生改变时,如果不绑定key值,vue就会在递归一次DOM与之前的DOM一层一层的做对比(diffing算法,改变树),进行修改dom,相当于重新渲染了一次页面
如果绑定了key值vue就清楚你修改的是哪个dom,直接对该dom进行修改即可,大大提高了效率

80.路由守卫

对路由进行权限控制

分类:全局守卫、独享守卫、组件内守卫

全局

前置 beforEach

后置 afterEach

路由独享

​ beforeEnter

组件内

beforeRouteEnter

beforeRouteUpdate

beforeRouteLeave

81.路由器的两种工作模式

对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

hash模式:
地址中永远带着#号,不美观 。
若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
兼容性较好。

history模式:
地址干净,美观 。
兼容性和hash模式相比略差。
应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。

82.返回上一级路由

第一种:history.back();

第二种:this.$router.go(-1);

83.依赖收集

在getter中收集依赖,在setter中触发依赖。先收集依赖,即把用到该数据的地方收集起来,然后等属性发生变化时,把之前收集好的依赖循环触发

Vue初始化的时候,挂载之后会进行编译。生成renderFunction。

当取值的时候,就会搜集watcher,放到dep里面。

当用户更改值的时候,就会通知watcher,去更新视图。

84.nexttick实现原理

nextTick是一个微任务。

  • nextTick中的回调是在下次Dom更新循环结束之后执行的延迟回调
  • 可以用于获取更新后的Dom
  • Vue中的数据更新是异步的,使用nextTick可以保证用户定义的逻辑在更新之后执行

85.vue组件之间的六种通信方式

父组件向子组件传值 props

组件中的数据共有三种形式:data、props、computed

子组件向父组件传值(通过事件形式) $emit

事件总线

通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件

Event.$emit(事件名,数据);
Event.$on(事件名,data => {});

vuex

86.vue中组件和插件的区别

组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件

组件可以降低系统的耦合度,提高可维护度

插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

  • 添加全局方法或者属性。如: vue-custom-element
  • 添加全局资源:指令/过滤器/过渡等。如 vue-touch
  • 通过全局混入来添加一些组件选项。如vue-router
  • 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如vue-router

区别

编写组件可以直接用一个.vue的文件,里面写组件内容,还可以用template属性编写一个组件

插件的实现需要暴露一个install方法,这个方法vue构造器,第二个参数是一个可选的选项对象

vue组件全局注册用vue.component,局部注册用components属性

插件注册用Vue.use 第一个参数是插件名,第二个参数是可选的配置项

使用的时候,组件用来构成app的业务模块

插件用来增强技术栈的功能模块

87.vue中的diff算法

是一种通过同层的树节点进行比较的高效算法

深度优先,同层比较

  1. 比较只会在同层级进行, 不会跨层级比较
  2. 比较的过程中,循环从两边向中间收拢

原理

当数据发生改变时,set方法会调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图

88.声明周期和执行顺序

beforeCreated(): 在组件创建之前触发
created(): 在组件创建后触发
beforeMounted(): 在组件挂载到页面之前触发
mounted(): 在组件挂载到页面之后触发
beforeUpdate(): 在某些数据改变触发页面重新渲染之前触发
updated(): 在某些数据改变触发页面重新渲染之后触发
beforeDestroy(): 在组件销毁之前触发
destroyed(): 在组件销毁之后触发

执行顺序

父组件 beforcreated created beforemount

子组件

子组件 mounted

父组件mounted

更新的时候

父组件 beforeupdate

子组件 beforeupdate

子组件 updated

父组件 updated

销毁的时候

父组件 beforedestroy

子组件

父组件 destroyed

子组件

数据请求放在哪

如果不需要获取dom,放在created里就行,如果需要 那就放在mounted里

89.虚拟DOM为什么会比真实DOM快

因为操作真实dom会导致render树的重新渲染,重新渲染会引发重绘和回流,这两个操作都很耗时

在浏览器里 ,渲染引擎和JS引擎是分离的,渲染引擎会暴露一些接口给JS调用,这里的通信也是要付出代价的;所以尽可能减少对DOM的操作可以达到性能优化的目的。

虚拟DOM用JS实现DOM树,减少了对真实DOM的操作次数。不会马上重新渲染,这样进一步减少了可能引发的重绘和回流的次数。

90.typeof判断null和undifined的区别

null是object

undefined是undefined

91.常见的类数组

arguments

92.v-module指令的修饰符

v-model.number-数字类型

v-model.trim-过滤首尾空白

v-model.lazy-失去焦点更新

93.Vue v-pre、v-once 指令

v-pre用来跳过当前节点的编译过程,加快编译速度。

v-once 定义它的元素或组件只会渲染一次

94.垃圾回收机制(GC机制)

在Js中主要有引用计数标记清除两种垃圾回收算法。
引用计数算法 主要是在IE6与IE7等低版本IE浏览器中使用。
标记清除算法 从根开始垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。
然后,它会去掉运行环境中的变量以及被环境中变量所引用的变量的标记。
此后,依然有标记的变量就被视为准备删除的变量,原因是在运行环境中已经无法访问到这些变量了。
最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

95.ajax跨域解决

ajax跨域的原理

出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,

同源是指,域名,协议,端口都必须相同

怎么解决
1、使用jsonp

2、服务器代理

3、在服务端设置response header中Access-Control-Allow-Origin字段。

96.vue的设计模式

vm 的设计模式。 mvvm 是 model-view-viewModel 的简写。 model 是数据模块,view 是渲染视图,viewModel 是沟通视图和数据模块的桥梁。

vue 中使用了哪些设计模式
1.工厂模式 - 传入参数即可创建实例

虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode

2.单例模式 - 整个程序有且仅有一个实例

vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉

3.发布-订阅模式 (vue 事件机制) 发布订阅模式的核心就是一对多的关系,一个发布者发起事件,所有的订阅者都会执行

4.观察者模式 (响应式数据原理)

5.装饰模式: (@装饰器的用法)在不改变原对象的基础上,通过对其添加属性或方法来进行包装拓展,使得原有对象可以动态具有更多功能
Actions是一个装饰器,它包裹Mutations使之可以异步使用。对于Store对象,使用Action可以异步改变状态;不用Actions也能使用Mutations来同步改变状态;使用Actions也不会改变State、Getters、Mutations的用法、结构

6.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略

97.动画

js里 setTimeout setinterval 可以实现

H5里的canvas也可以实现

requestAnimationFrame 请求动画帧

该方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。 该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。

98.为什么usestate使用数组不使用对象(react)

降低使用的复杂度,返回数组的话可以直接根据顺序解构,而返回对象的话要想使用多次就得定义别名了

99.高阶函数和高阶组件的区别(react)

高阶函数:高阶函数是指函数可以作为另一个函数的参数或者返回值。

高阶组件:是接收一个组件作为参数,并返回一个新组件的函数。

高阶组件是一个函数

100.组件传值组件通信的方案(react)

父子组件之间用props
兄弟之间用bus
层级组件之间用 层层props或者context

为什么react里没有vue中的声明周期什么的

什么模板编译精准更新什么的,这块没太记得住

你可能感兴趣的:(前端面试题,前端,面试,javascript)