React 组件动态加载

React 的 setState 怎么实现的异步操作

React 官网对 setState 的说明:
将 setState() 认为是一次请求而不是一次立即执行更新组件的命令。为了更为客观的性能,React 可能会推迟它,稍后一次性更新这些组件。React 不会保证在 setState 之后,能够立刻拿到改变的结果。

  1. setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的;
  2. setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过 setState 的第二个参数中的 callback 拿到更新后的结果;
  3. setState 的批量更新优化也是建立在“异步”之上的,在原生事件和 setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState,setState 的批量更新策略就会对其进行覆盖,取最后一次的执行,如果同时 setState 多个不同的值,在更新时会对其进行批量更新。

如果想让 setState 立即执行怎么实现

讲一讲 React 的高阶组件

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

高阶组件是参数为组件,返回值为新组件的函数。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

HOC 不会修改传入的组件,也不会使用继承来复制其行为。相反,HOC 通过将组件包装在容器中来组成新组件。HOC 是纯函数,没有副作用。
被包装组件

React 怎么做到将 JSX 转换为 DOM 树的

React 怎么减少 DOM 变动次数的

一个页面中多个 tab, 不用 Redux,怎么实现数据共享?

Localstorage 有过期时间吗?怎么实现?

JS 怎么捕获路由变化

如果是哈希路由变化的话,直接给 window 绑定 'hashchange' 事件;
普通路由 'popstate' 事件在调用 history.back()、history.forward()、history.go() 方法后会触发,而 history.pushState() 和 history.replaceState() 并不会触发 popState 事件,怎么办呢?

网路上有一篇 JS 监听 history 路由变化的文章

// 订阅-发布模式

JS 怎么捕获脚本运行错误

CSRF、XSS 攻击的原理以及怎么防范

简述浏览器输入 URL 到浏览器出现页面的过程

为什么 JS 的脚本时,会停止 DOM 树的解析

JS 怎么异步编程的方法?

  • 回调函数
    回调函数是异步编程最基础的方法。举例一个最简单的回调:在 f1 执行完之后再执行 f2
var func1 = function(){
    console.log(1);
    if(callback && typeof(callback) === 'function'){
        callback();    
    }
}

var func2 = function(){
    console.log(2);
}

func1(func2); // 输出 1,2

异步回调最常见的就是 Ajax

$.ajax({
    url: "/getmsg",
    type: "get",
    dataType: 'json',
    success: function(ret){
        if(ret && ret.status){
            //
        }
    },
    error: function(xhr){
        //
    }
})
  • 事件监听
  • 发布/订阅
  • promise
  • generator (ES6)
  • async/await (ES7)

微任务与宏任务有什么区别

JS 有哪些设计模式

设计模式

设计模式:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方法。

  1. 观察者模式:观察者模式定义了对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。
  1. 订阅-发布模式:在现在的订阅-发布模式中,发布者的消息不会直接发送给订阅者,这意味着发布者和订阅者都不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有的发布者传入的消息,并相应的分发给他们的订阅者。

观察者模式和订阅发布最大的区别是订阅-发布模式有事件调度中心
观察者模式有具体目标调度,每个被订阅的目标里面都需要对观察者的处理,这种处理方式可能造成代码的冗余;
订阅-发布模式中,统一由调度中心进行处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。这样一方面实现了解耦,另一方面可以实现更加细粒度的控制。比如发布者发布了很多消息,但不是所有的订阅者都希望收到,就可以在调度中心做一些处理,类似权限控制之类的。还可以做一些节流操作。

为什么选择的是 React,而不是 Vue

讲一下 js 的基础类型 symbol

symbol 是一种基本数据类型。每个从 Symbol() 返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。

Symbol('foo') !== Symbol('foo')    // true
var sym = new Symbol()   // TypeError
// 在对象中查找 Symbol 属性
Object.getOwnPropertySymbols() 
// 方法
// Symbol.for()
Symbol.for('bar') === Symbol.for('bar') // true
// Symbol.keyFor()
// 创建一个 symbol,并放入 Symbol 注册表,key 为 "foo"
var globalSym = Symbol.for("foo");
Symbol.keyFor(globalSym)  // "foo"
// 创建一个 symbol,但是并不放入注册表里,key 为 "song"
Symbol.keyFor("song") // undefined

同源策略

scheme、host、port 都相同则为同源;
非同源站点有这样的限制:

  1. 不能读取和修改对方的 DOM;
  2. 不能访问对方的 Cookie、IndexDB和LocalStorage等;
  3. 限制 XMLHttpRequest 请求;

有哪些跨域请求的方法

CORS、Jsonp、Nginx反向代理

讲一下 Nginx 反向代理

Nginx 是一种高性能的反向代理服务器,,可以轻松用来解决跨域问题;
正向代理帮助客户端访问客户端访问不到的服务器,然后将结果返回客户端;
反向代理拿到客户端的请求,将请求转发给其他的服务器,主要的场景是维持服务器集群的负载均衡,换句话说,反向代理帮其他的服务器拿到请求,然后选择一个合适的服务器,将请求转交给它。
也就是说,正向代理服务器是帮客户端做事情,而反向代理服务器是帮其他的服务器做事情。
现在客户端的域名是 client.com,服务器的域名是 server.com,客户端向服务器发送 Ajax 请求,属于跨域。

// server 代表一个服务
server {
    listen 80;
    server_name client.com;
    location /api {
        proxy_pass server.com;
    }

Nginx 相当于一个跳板机,这个跳板机的域名是 client.com,让客户端首先访问 client.com/api,这当然没有跨域,然后 Nginx 服务器作为反向代理,将请求转发给 server.com,当响应返回时,又将响应给到客户端,这就完成了整个跨域请求的过程。

块级元素和 inline 元素的区别

怎么让两个块级元素在同一行

浮动会造成什么后果,怎么解决

一个 a.cn 的服务器请求一个 b.cn 的服务器,会触发同源策略吗?

用户怎么实时的获取服务器更新信息

讲一下 Webpack 的作用

字符串去重怎么做

了解 Web Workers 吗

讲一下 CSS 的动画实现

讲一下 rem

怎么实现响应式布局

复盘

二面完全崩了,几乎一题都没回答上来,React 框架的原理完全不懂,要尽快补上。。。。。。