30 道前端面试题包含 JS、CSS、React、网络、浏览器、程序题等 出处:https://segmentfault.com/a/1190000020391424
题 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、 这几个角度考虑。 模块化主要是用来抽离公共代码,隔离作用域,避免变量冲突等。
IIFE:使用自执行函数来编写模块化,特点:
在一个单独的函数作用域中执行代码,避免变量冲突。
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 为例):
当前 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步,如果没有则停止。