面试总结-2

76 阅读7分钟

对webpack的理解?

webpack 是用于 JavaScript 应用程序的静态模块打包工具。我们可以使用webpack管理模块。在webpack看来,项目中的所有资源皆为模块,通过分析模块间的依赖关系,在其内部构建出一个依赖图,最终编绎输出模块为 HTML、JavaScript、CSS 以及各种静态文件(图片、字体等),让我们的开发过程更加高效。

webpack的主要作用:

  • 模块打包:将不同模块的文件打包整合在一起,保证他们之间引用正确,利用打包可以实现在开发中根据业务需求自由划分文件模块,保证项目结构的清晰性和可读性。
  • 编译兼容:通过webpack的Loader机制,不仅仅可以帮助我们对代码做polyfill,还可以编译转换诸如.less.vue.jsx这类在浏览器无法识别的格式文件,让我们在开发的时候可以使用新特性和新语法做开发,提高开发效率。
  • 能力扩展:通过webpack的Plugin机制,在我们实现模块打包和编译兼容的基础上,进一步实现按需加载代码压缩等功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。

webpack的构建流程?

  1. webpack的运行流程是一个串行的过程
  2. 初始化参数 从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
  3. 开始编译 用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
  4. 确定入口 根据配置中的 entry 找出所有的入口文件
  5. 编译模块 从入口文件出发,调用所有配置的 loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
  6. 完成模块编译 在经过上一步使用 loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
  7. 输出资源 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
  8. 输出完成 在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
简单说:
  • 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
  • 编译:从 entry 出发,针对每个 Module 串行调用对应的 loader 去翻译文件的内容,再找到该 Module 依赖的 Module,递归地进行编译处理
  • 输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中

git命令补充

  • 初始化一个仓库:git init

  • 查看分支:git branch

  • 将已修改或未跟踪的文件添加到暂存区:git add .

  • 提交至本地仓库:git commit -m "提及记录xxxx"

  • 本地分支推送至远程分支:git push

  • 查看当前工作目录和暂存区的状态: git status

  • 查看提交的日志记录: git log

  • 从远程分支拉取代码:git pull

  • 合并某分支(xxx)到当前分支: git merge xxx

  • 切换到分支xxx:git checkout xxx

  • 创建分支xxx并切换到该分支:git checkout -b xxx

  • 删除分支xxx:git branch -d xxx

  • 将当前分支到改动保存到堆栈中:git stash

  • 恢复堆栈中缓存的改动内容:git stash pop

webpack的热更新原理:

模块热替换又叫热更新,在不需要刷新整个页面的同时更新模块,能够提升开发的效率和用户体验度,热更新只会局部刷新页面上发生变化的模块,同时可以保留当前页面的状态,比如复选框的选中状态。

热更新的核心就是客户端从服务端拉取更新后的文件,准确的说是chunk diff,实际上webpack-dev-server与浏览器之间维护了一个websocket ,当本地资源发生变化时,会向浏览器推送更新,并带上构建时的hash,让客户端与上一次资源进行对比客户端对比出差异后会向webpack-dev-server发起 Ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向webpack-dev-server发起 jsonp 请求获取该chunk的增量更新。

后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loadervue-loader都是借助这些 API 实现热更新。

JS基本数据类型(8种)

Undefined 、 Null 、 Boolean 、 Number 、 String 、 Object 、 Symbol 、 BigInt

其中 Symbol  和 BigInt  是 ES6 新增的数据类型:
  • Symbol 代表独一无二的值,最大的用法是用来定义对象的唯一属性名。
  • BigInt 可以表示任意大小的整数。

一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么

  1. 浏览器查找域名对应的ip地址(DNS查询:浏览器缓存->系统缓存->路由器缓存->ISPDNS缓存->根域名服务器)
  2. 浏览器向web服务端发送一个HTTP请求(TCP三次握手)
  3. 服务器301重定向
  4. 浏览器跟踪重定向地址,请求一个带www的地址
  5. 服务器处理请求
  6. 服务器返回一个HTTP响应

for in 和for of的区别

  • 推荐在循环对象属性的时候使用for-in遍历数组的时候用for-of
  • for--in循环出key,for--of循环出value
  • for--of是ES6新引入的特性,修复了ES5引入的for--in的不足 -for--of不能循环普通的对象,需要通过Object.keys()搭配使用

防抖和节流

如果调用事件处理函数没有次数限制,会加重浏览器的负担,用户体验感差 采用防抖和节流的方式来减少调用的频率,同时又不影响实际的效果。

1.防抖:假如某个事件频繁地被触发,防抖可以使得事件被触发后的第n秒之间只执行一次(关键词搜索功能,用户输入时用防抖节约请求资源)

  • 原理:setTimeOut定时器

2.节流:某个事件频繁地被触发,节流函数使得程序每隔n秒执行一次(触底加载、鼠标点击)

new操作符具体干了什么(实例化构造函数过程中做了什么)

  1. 创建一个空对象(并且this变量引入该对象,同时继承了函数的原型)
  2. 设置原型链,改变隐式原型的指向(空对象指向构造函数的原型对象)
  3. 改变构造函数this的指向
  4. 判断有无返回对象(没有就创建一个对象)

对this的理解

  1. 普通函数中,this指向全局对象window
  2. 定时器中,this指向调用对象的window
  3. 构造函数中,this指向当前实例化对象
  4. 事件处理函数中,this指向事件触发对象 js中一般理解为谁调用就指向谁。

如何区分数组或对象

  • 方法一 Array.isArray (是数组,true 否则为false)
  • 方法二 instanceof (可以用来判断数组 是数组true 对象为false)
  • 方法三 constructor ({}.constructor=>object [ ].constructor=>array)
  • 方法四 Object.prototype.toString.call (object array/object object)