知识点“大杂烩”

170 阅读5分钟

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组件间有哪些通信方式?

  1. 通过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;

  1. 使用redux 或者Mobx

  2. 使用订阅发布模式

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隔离兼容样式