题 1 :什么是防抖和节流?有什么区别?如何实现?
**防抖:**触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
**思路:**每次触发事件时都取消之前的延时调用方法
**节流:**高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率
**思路:**每次触发事件时都判断当前是否有等待执行的延时函数
题 2 :get请求传参长度的误区、get和post请求在缓存方面的区别误区:我们经常说get请求参数的大小存在限制,而post请求的参数大小是无限制的。
实际上 HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对 get 请求参数的限制是来源与浏览器或 web 服务器,浏览器或 web 服务器限制了 url 的长度。为了明确这个概念,我们必须再次强调下面几点:
- HTTP 协议未规定 GET 和 POST 的长度限制
- GET 的最大长度显示是因为浏览器和 web 服务器限制了 URI 的长度
- 不同的浏览器和 WEB 服务器,限制的最大长度不一样
- 要支持 IE,则最大长度为 2083byte,若只支持 Chrome,则最大长度 8182byte
补充补充一个 get 和 post 在缓存方面的区别:
- get 请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。
- post 不同,post 做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此 get 请求适合于请求缓存。
题 3:模块化发展历程
可从IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、
AMD:使用 requireJS 来编写模块化,特点:依赖必须提前声明好。
CMD:使用 seaJS 来编写模块化,特点:支持动态引入依赖文件。
CommonJS:nodejs 中自带的模块化。
UMD:兼容 AMD,CommonJS 模块化语法。webpack(require.ensure):webpack 2.x 版本中的代码分割。ES Modules:ES6 引入的模块化,支持 import 来引入另一个 js 。
题 4:npm模块安装机制,为什么输入 npm install 就可以自动安装对应的模块?
1. npm 模块安装机制:
- 发出npm install命令
- 查询node_modules目录之中是否已经存在指定模块
- 若存在,不再重新安装
- 若不存在
- npm 向 registry 查询模块压缩包的网址
- 下载压缩包,存放在根目录下的.npm目录里
- 解压压缩包到当前项目的node_modules目录
2. npm 实现原理输入 npm install 命令并敲下回车后,会经历如下几个阶段(以 npm 5.5.1 为例):
- 执行工程自身 preinstall
当前 npm 工程如果定义了 preinstall 钩子此时会被执行。
- 确定首层依赖模块
首先需要做的是确定工程中的首层依赖,也就是 dependencies 和 devDependencies 属性中直接指定的模块(假设此时没有添加 npm install 参数)。工程本身是整棵依赖树的根节点,每个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每个首层依赖模块开始逐步寻找更深层级的节点。
-
获取模块获取模块是一个递归的过程,分为以下几步:
-
获取模块信息。在下载一个模块之前,首先要确定其版本,这是因为 package.json 中往往是 semantic version(semver,语义化版本)。此时如果版本描述文件(npm-shrinkwrap.json 或 package-lock.json)中有该模块信息直接拿即可,如果没有则从仓库获取。如 packaeg.json 中某个包的版本是 ^1.1.0,npm 就会去仓库中获取符合 1.x.x 形式的最新版本。
-
获取模块实体。上一步会获取到模块的压缩包地址(resolved 字段),npm 会用此地址检查本地缓存,缓存中有就直接拿,如果没有则从仓库下载。
-
查找该模块依赖,如果有依赖则回到第1步,如果没有则停止。
-
模块扁平化(dedupe)
上一步获取到的是一棵完整的依赖树,其中可能包含大量重复模块。比如 A 模块依赖于 loadsh,B 模块同样依赖于 lodash。在 npm3 以前会严格按照依赖树的结构进行安装,因此会造成模块冗余。从 npm3 开始默认加入了一个 dedupe的过程。它会遍历所有节点,逐个将模块放在根节点下面,也就是 node-modules 的第一层。当发现有重复模块时&#x