- 问了前端使用什么框架编写。
- 项目主要使用到了哪些hooks。
使用useState,useEffect. - 你还了解哪些hook。(usecallback,useref),usecallback的应用场景,主要原理机制,用过react.memo吗以及两者的区别。
usecallback usememo区别
前提:react 的父组件发生重新渲染时,其所有的(状态,局部变量)都是新的,一旦子组件中对象依赖某个父组件,无论对象是否变化,子组件都是拿到新的对象,从而使diff失效。
应用场景:当父组件发生更新时,只有子组件的依赖项发生变化时,再出发数据请求。否则不触发。
原理:进行缓存。
区别:
useMemo允许缓存传入的一个对象,仅当依赖性发生变化是,才重新计算并更新相应的对象。
使用useCallbcck支持缓存某一个函数,当且仅当依赖项发生变化时才更新该函数,
const a = useCallback(() => {
return function() {
console.log(b)
}
},[b])
console.log(a)
console.log(a())
通过hooks的配合,使函数不仅仅是一个方法,还可以作为一个值参与到应用的数据流中。(react hooks在数据流上带来的变化有两点:1支持更友好的使用context进行状态管理避免层级过多时中间层承载无关参数,2。允许函数参加到数据流中,避免向下层组件传入多余参数。)
5. react fiber了解过吗,具体底层实现原理是什么。
在React V15 在渲染时,会递归比对 VirtualDOM 树,找出需要变动的节点,然后同步更新它们, 一气呵成。这个过程期间, React 会占据浏览器资源,这会导致用户触发的事件得不到响应,导致用户感觉到卡顿。
React 通过Fiber 架构,让这个执行过程变成可被中断。“适时”地让出 CPU 执行权,可以让浏览器及时地响应用户的交互,它只是一种控制流程的让出机制。让出 CPU 的执行权,让 CPU 能在这段时间执行其他的操作。
知乎关于react fiber
react fiber
https://zhuanlan.zhihu.com/p/390409316
React16提出了Fiber结构,其能够将任务分片,划分优先级,同时能够实现类似于操作系统中对线程的抢占式调度,非常强大。
react 中从render方法返回的不可变React元素树通常称为“Virtual DOM”。这个术语有助于早期向人们解释React,,并且不再在React文档中使用。将称它为React元素的树。除了React元素的树之外,框架总是有一个用于保持状态的内部实例树(internal instances)(组件,DOM节点等),与之相对的是跟具体平台有关的public instance,也被称为Host instance。
React推出了对内部实例树的新实现以及负责操作树的算法,被称为Fiber。fiber作为一种数据结构,提供了一种跟踪,调度,暂停和中止工作的便捷方式
在reconciliation期间(React是一个用于构建UI的JavaScript库,其核心是跟踪组件状态变化并将更新到view上,我们将此过程视为reconciliation),来自render方法返回的每个React元素的数据,被合并到fiber node树中,每个React元素都有一个相应的fiber node。与React元素不同,每次渲染过程,不会再重新创建fiber。
当React元素第一次转换为fiber节点时,React使用createElement返回的数据来创建fiber。在随后的更新中,React重用fiber节点,并使用来自相应React元素的数据来更新必要的属性。如果不再从render方法返回相应的React元素,React可能还需要根据key来移动层次结构中的节点或删除它。
react fiber如何工作
当前被刷新用来渲染用户界面的树,被称为 current,它用来渲染当前用户界面。每当有更新时,Fiber 会建立一个 workInProgress 树,它是由 React 元素中已经更新数据创建的。React 在这个 workInProgress 树上执行工作,并在下次渲染时使用这个更新的树。一旦这个 workInProgress 树被渲染到用户界面上,它就成为 current 树。
React Fiber 中的时间分片
把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。
React Fiber 把更新过程碎片化,每执行完一段更新过程,就把控制权交还给 React 负责任务协调的模块,看看有没有其他紧急任务要做,如果没有就继续去更新,如果有紧急任务,那就去做紧急任务。
在 React Fiber 中用链表遍历的方式替代了 React 16 之前的栈递归方案
正文
7. 需求:如果一个js正在运行,暂停当前js,先去执行别的js。回答yield,使用生成器中的yield,通过,next()来暂停。
8. 使用过call,bind,apply吗,能实现一个call方法吗?(call是用来改变this指向,实现call方法可以使用原型链)
call,apply,bind的区别
call 和 apply 的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。
bind 也能改变对象的执行上下文,它与 call 和 apply 不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。
实现call。
Function.prototype.call = function (context, ...args) {
let context = context || window;
let fn = Symbol('fn');
context.fn = this;
let result = eval('context.fn(...args)');
delete context.fn
return result;
}
-
了解过原型链吗,什么是原型链。
JavaScript对象通过__proto__ 指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条, 即原型链。 -
null undefine的区别。
undefined 是一个没有设置值的变量。typeof 一个没有值的变量会返回 undefined
在 JavaScript 中 null 表示 “什么都没有”。null是一个只有一个值的特殊类型。表示一个空对象引用。
1.类型不同,typeof null===‘object’ , typeof undefine= = =‘undefine’,
2.'null’上执行算术转换时,则值为0,“undefined”不执行任何此类转换,得到NaN。 -
null===null吗?(答案不等,开始回答相等,问了 = = =的使用)
-
promise了解过吗,简单说一下 ,promise all了解过吗?promise race(忘记了),问了有一点点多,我回答的适合说了使用catch、,问catch能捕捉到返回异常吗?因为回答的不正确吧,所以让手写实现promise all(没写出来)。
promise all与promise race区别
手写promise all
const PromiseAll = (iterator) => {
const promises = Array.from(iterator); // 对传入的数据进行浅拷贝,确保有遍历器
const len = promises.length; // 长度
let index = 0; // 每次执行成功+1,当等于长度时,说明所有数据都返回,则可以resolve
let data = []; // 用来存放返回的数据数组
return new Promise((resolve, reject) => {
for (let i in promises) {
promises[i]
.then((res) => {
data[i] = res;
if (++index === len) {
resolve(data);
}
})
.catch((err) => {
reject(err);
});
}
});
};
const promise1 = Promise.resolve('promise1');
const promise2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 2000, 'promise2');
});
const promise3 = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, 'promise3');
});
PromiseAll([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
const race=function(arr){
return new Promise((resolve,reject)=>{
arr.forEach((item,i) => {
Promise.resolve(item).then(val=>{
resolve(val)
},err=>{
reject(err)
})
});
})
}