1. 利用 flex 实现左边固定宽度100px,右边自适应

.container {
    display: flex;
    width: 100vw;
    height: 100vh;
}
.left {
    flex-basis: 100px;
    background-color: blueviolet;
}
.right {
    flex: 1;
    background-color: red;
}

2. 看代码说输出

var a= function () { this.b =3; }
var c = new a();
a.prototype.b = 9;
var b = 7;
a();
console.log(b); // 输出 3
console.log(c.b); // 输出 3

3. 红灯三秒亮一次,黄灯 2 秒亮一次,绿灯一秒亮一次;如何让三个灯不断交替重复亮灯?(用 Promise 实现)

function log(){
    console.log.apply(console, arguments);
}

function light(color){
    log(color);
}

function lightDelay(color, delay){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            setTimeout(() => {
                light(color);
                resolve();
            }, delay);
        })
    });
}

function oneIter(){
    lightDelay('red', 3000)
    .then(() => {
        return lightDelay('yellow', 2000);
    })
    .then(() => {
        return lightDelay('green', 1000);
    });
}

setInterval(() => {
    oneIter();
}, 6000);

4. React Hooks 的优点和缺点

5. 浏览器缓存机制

简介

简单来说,浏览器缓存就是把一个已经请求过的 Web 资源拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求进来的时候,如果是相同的 URL ,缓存会根据缓存机制决定是直接使用副本响应,还是向源服务器再次发送请求。

为什么使用缓存

(1) 减少网络带宽消耗;
(2) 降低服务器压力;

6. arguments 介绍一下

arguments 是一个对应于传递给函数的参数的类数组对象
arguments 是一个类数组对象;

arguments 转换为数组

(1) Array.from(arguments);
(2) [...arguments];
(3) [].slice.call(arguments);

7. null 和 undefined 的区别

目前,null 和 undefined 基本是同义的,只有一些细微的差别。
null 表示“没有对象”,即此处不该有值。典型用法:

  • 作为函数的参数,表示该函数参数的对象不是对象;
  • 作为对象原型链的终点;

undefined 表示“缺少值”,就是此处应该有一个值,但是没有定义。典型用法:

  • 变量被声明了,但是没有赋值时,就等于 undefined;
  • 调用函数时,应该提供的参数没有提供,该参数等于 undefined;
  • 对象没有赋值的属性,该属性的值是 undefined;
  • 函数没有返回值时,默认返回 undefined;

8. 怎么判断一个变量是不是数组类型

  1. variable instanceof Array;
  2. Array.isArray();
  3. Object.prototype.call(variable).indexof('Array') !== -1;
  4. variable.constructor.toString().indexOf('Array') !== -1;

9. 引用类型和基本类型的区别

10. 栈和堆的区别

堆和栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下集中区别:
(1) 管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的分配和释放工作由程序员控制,容易产生内存泄***r>(2)空间大小不同。每个进程拥有的栈的大小要远远小于堆的大小。理论上,程序员可申请的堆的大小为虚拟内存的大小,进程栈的大小 64 bits 默认 1MB,64 bits 的 Linux默认 10MB;
(3)生长方向不同。堆的生长方向上内存地址由低到高;栈的生长方向向下,内存地址由高到低;
(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由 malloc 函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由操作系统进行释放,无需自己手动实现;
(5)存放内容不同。栈中一般存储基本类型和引用类型的地址,堆中一般存放对象。
(6)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是 C/C++ 提供的库函数或运算符完成申请和管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率要比栈要低的多。

11. JSX 语法的理解

12. 有一个 input 框,实现 10 秒只提交一次,封装好函数

// 节流的核心思想:如果在定时器的时间范围内再次触发则不予理睬,
// 等当前定时器完成,才能启动下一个定时器任务。
// (1) 运用 setTimeout 来定时
function throttle1(fn, interval){
    let flag = true;
    return function(...args){
        let context = this;
        if(!flag){
            return;
        }
        flag = false;
        setTimeout(() => {
            fn.apply(context, args);
            flag = true;
        }, interval);
    }
}

// (2)运用 Date 来计时
function throttle2(fn, interval){
    let last = 0;
    return function(...args){
        let now = new Date();
        // 如果触发时间小于 interval, 直接返回
        if(now - last < interval){
            return;
        }
        // 触发时间大于 interval,则把当前时间赋值给 last,并且执行函数 fn
        last = now;
        fn.apply(this, args);
    }
}

13. 为什么 React 要构建虚拟 DOM 树

1. 减少 DOM 操作

虚拟 DOM 一个优点表现在它可以减少 DOM 操作。而且虚拟 DOM 的优势不在于单次的操作,用对比的算法,它可以将多次操作合并成一次操作,在大量频繁的的数据更新下,能够对试图进行合理、高效的更新。

2. 跨平台

虚拟 DOM 的另一个优点就是跨平台。由于虚拟 DOM 是以 JS 对象为基础的,它的本质就是一个 JS 对象,并不依赖真实平台环境,所以使它具有了跨平台的能力。

14. 为什么 React map 渲染数组元素时,需要加个 key

15. 讲讲 DOM DIFF 算法

16. React 是怎么防范 XSS 攻击的

XSS(Cross Site Scripting),为了和 CSS 区分,所以叫它 XSS。 XSS 攻击是指浏览器中执行恶意脚本(无论是跨域还是同域),从而拿到用户的信息并进行操作。

XSS 可以做到下面这些事情:

  1. 窃取 Cookie;
  2. 监听用户行为,比如输入账户密码后,直接发送到黑客服务器;
  3. 修改 DOM 伪造登陆表单;
  4. 在页面中生成浮窗广告;

XSS 攻击的原理就是让恶意脚本在浏览器中执行;所以防范它:

  1. 一个信念:不要相信任何用户的输入,无论在前端还是服务端,都要对用户的输入进行转码或者过滤;
  2. 利用 CSP(浏览器中的安全策略),核心思想就是服务器决定浏览器加载那些资源;
  3. 设置 Cookie 的 HttpOnly 属性后,JS 将无法读取 Cookie 的值,这样可以很好的防范 XSS 攻击;

17. 箭头函数与普通函数有什么区别

(1) 箭头函数作为匿名函数不能够作为构造函数,不能使用 new;
(2) 箭头函数不绑定 arguments, 用 rest 参数 ... 代替;
(3) 箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值;
(4) 箭头函数当方法使用的时候没有定义 this 绑定;
(5) 使用 call 或 apply 调用时,只是传入了一个参数,对 this 并没有什么影响;
(6) 箭头函数没有原型属性;

复盘

Promise 题一开始没写出来就急了,调试根本集中不了注意力在题目上。朋友们,面试一定要耐心冷静;