1、new Function 语法
let a = new Function(); function 由两部分:call和constructor 构成。如果直接调用函数:则只调用call,使用new返回一个object,可以通过call修改this指向。
箭头函数 不能使用new 构造,箭头函数没有constructor 、argument等属性。
2、object.is(a,b)与“===”基本上一致,区别在于 “===” 判定 +0 === -0 为true,NaN === NaN 为false;object.is()恰好相反
3、export和export default的区别
export 与export default 均可用于导出常量、函数、文件、模块,可在其他文件或者模块中通过import 方式将其导入,以便能够对其进行使用,在一个文件或模块中,export、import 可以有多个,export default 仅有一个,通过export 方式导出,在导入时要加 {},export default 则不需要。
4、history.push
- 实现无刷新跳转:可以改变网址而不刷新页面
- 存在跨域问题,不支持重写到另一个域名下-不支持跨域
- 仅改变网址,网页不会真的跳转,也不会获取到新的内容,本质上网页还停留在原页面
5、history.pushState(data,title,targetUrl)
- 状态对象:传给目标路由的信息,可为空
- 页面标题:目前所有浏览器都不支持,填空字符串即可
- url:目标url,不会检查url是否存在,且不能跨域。如不传该项,即给当前url添加data
6、history.replaceState
类似于pushState,但是会直接替换掉当前url,而不会在history中留下记录,即无法history.back
7、arr.reduce(callback, [initValue])
- callback: 对数组每个元素执行的回调函数
- initValue: 初始值 他的功能可以由for 或者forEach完成,逼格更高
8、setState 是异步还是同步?
- 合成事件中是异步
- 钩子函数中的是异步
- 原生事件中是同步
- setTimeout中是同步
9、useEffect(fn, [])和componentDidMount有什么差异?
useEffect 会捕获props和state,所以即便在回调函数里,拿到的还是初始的props和state。如果想得到“最新”的值,可以使用 ref。
10、hooks为什么不能放在条件判断里?
以setState为例,在react 内部,每个组件(Fiber)的hooks都是以链表的形式存在memoizeState属性中:
update 阶段,每次调用setState,链表就会执行next 向后移动一步。如果将setState写在条件判断中,假设条件判断不成立,没有执行setState方法,会导致接下来所有的setState的取值出现偏移,从而导致异常发生。
11、fiber是什么?
react fiber是一种基于浏览器的单线程调度算法。
其用类似requestIdleCallback(待补充)的机制来做异步diff。但是之前数据结构不支持这样的实现异步diff,于是React实现了一个类似链表的数据结构,将原来的递归diff 变成了现在的遍历diff,这样就能做到异步可更新了
12、调用setState之后发生了什么?
在 setState 的时候,React 会为当前节点创建一个 updateQueue 的更新列队。
然后会触发 reconciliation 过程,在这个过程中,会使用名为 Fiber 的调度算法,开始生成新的 Fiber 树, Fiber 算法的最大特点是可以做到异步可中断的执行。
然后 React Scheduler 会根据优先级高低,先执行优先级高的节点,具体是执行 doWork 方法。
在 doWork 方法中,React 会执行一遍 updateQueue 中的方法,以获得新的节点。然后对比新旧节点,为老节点打上 更新、插入、替换 等 Tag。
当前节点 doWork 完成后,会执行 performUnitOfWork 方法获得新节点,然后再重复上面的过程。
当所有节点都 doWork 完成后,会触发 commitRoot 方法,React 进入 commit 阶段。
在 commit 阶段中,React 会根据前面为各个节点打的 Tag,一次性更新整个 dom 元素。
13、为什么虚拟dom会提高性能?
虚拟dom相当于在JS和真实dom中间加了一个缓存,利用diff算法避免了没有必要的dom操作,从而提高性能。
14、什么是Portals?
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。
ReactDOM.createPortal(child,container)
15、react组件间有哪些通信方式?
- 通过props传递 - 父子组件通信,跨层级通信 使用react自带的context 进行通信, createContext 创建上下文, useContext使用上下文。
import React, { createContext, useContext } from 'react';
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button
style={{ background: theme.background, color:theme.foreground }}
>
I am styled by theme context!
</button>
);
}
export default App;
-
使用redux 或者Mobx
-
使用订阅发布模式
16、React中ref的几种用法
- ref = 字符串,通过this.refs.a来引用真实dom节点--dom节点上使用
<input type ="text" ref="a"/>
- ref = 回调函数,回调函数就是在dom节点或组件上挂载函数,函数的入参是dom节点或组件实例,达到的效果与字符串形式是一样的,都是获取其引用。
<input type="text" ref={(input)=>{**this**.textInput=input}}
- React.createRef(),在React 16.3之后,使用此方法来创建ref.将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性将能拿到dom节点或组件的实例
class Counter extends Component {
constructor() {
super()
this.state ={sum:0,number:0}
this.myRef = React.createRef();
}
change = () =>{
this.setState({...this.state,
sum: Number(this.textInput.value) +
Number(this.myRef.current.value)})
}
componentDidMount(){
console.log(this.myRef.current.value);
}
render() {
return (
<div onChange ={**this**.change} >
<input type="text"
ref={(input) => {this.textInput=input}}
/>
+
<input type ="text" ref={this.myRef} />
= {this.state.sum}
</div>
)
}
}
17、滚动穿透问题解决
// 在出现蒙层处 设置
position: fixed;
left: 0;
top: 0;
overflow: hidden;
18、适配苹果X
网页默认不添加扩展的表现是 viewport-fit=contain,需要适配 iPhoneX 必须设置 viewport-fit=cover,这是适配的关键步骤。 同时: env() 是在 iso > =11.2 constant() 是在ios<11.2 ,因此要做兼容。
// safe-area-inset-left: 安全区域距离左边边界 距离
// safe-area-inset-right: 安全区域距离右边边界 距离
// safe-area-inset-top: 安全区域距离顶部边界 距离
// safe-area-inset-bottom: 安全区域距离底部边界 距离
// 例子
padding-bottom: constant( safe-area-inset-bottom); // 兼容 IOS < 11.2
padding-bottom: env( safe-area-inset-bottom); // 兼容 *iOS >= 11.2
// 注意:env() 跟 constant() 需要同时存在,而且顺序不能换。
// 使用@supports隔离兼容样式