对webpack的理解?
webpack 是用于 JavaScript 应用程序的静态模块打包工具。我们可以使用webpack管理模块。在webpack看来,项目中的所有资源皆为模块,通过分析模块间的依赖关系,在其内部构建出一个依赖图,最终编绎输出模块为 HTML、JavaScript、CSS 以及各种静态文件(图片、字体等),让我们的开发过程更加高效。
webpack的主要作用:
- 模块打包:将不同模块的文件打包整合在一起,保证他们之间引用正确,利用打包可以实现在开发中根据业务需求自由划分文件模块,保证项目结构的清晰性和可读性。
- 编译兼容:通过webpack的
Loader机制,不仅仅可以帮助我们对代码做polyfill,还可以编译转换诸如.less,.vue,.jsx这类在浏览器无法识别的格式文件,让我们在开发的时候可以使用新特性和新语法做开发,提高开发效率。 - 能力扩展:通过webpack的
Plugin机制,在我们实现模块打包和编译兼容的基础上,进一步实现按需加载,代码压缩等功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。
webpack的构建流程?
webpack的运行流程是一个串行的过程- 初始化参数 从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
- 开始编译 用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
- 确定入口 根据配置中的 entry 找出所有的入口文件
- 编译模块 从入口文件出发,调用所有配置的 loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
- 完成模块编译 在经过上一步使用 loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
- 输出资源 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
- 输出完成 在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
简单说:
- 初始化:启动构建,读取与合并配置参数,加载 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-loader和vue-loader都是借助这些 API 实现热更新。
JS基本数据类型(8种)
Undefined 、 Null 、 Boolean 、 Number 、 String 、 Object 、 Symbol 、 BigInt
其中 Symbol 和 BigInt 是 ES6 新增的数据类型:
- Symbol 代表独一无二的值,最大的用法是用来定义对象的唯一属性名。
- BigInt 可以表示任意大小的整数。
一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么
浏览器查找域名对应的ip地址(DNS查询:浏览器缓存->系统缓存->路由器缓存->ISPDNS缓存->根域名服务器)浏览器向web服务端发送一个HTTP请求(TCP三次握手)- 服务器301重定向
- 浏览器跟踪重定向地址,请求一个带www的地址
- 服务器处理请求
- 服务器返回一个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操作符具体干了什么(实例化构造函数过程中做了什么)
- 创建一个空对象(并且this变量引入该对象,同时继承了函数的原型)
- 设置原型链,改变隐式原型的指向(空对象指向构造函数的原型对象)
- 改变构造函数this的指向
- 判断有无返回对象(没有就创建一个对象)
对this的理解
- 普通函数中,this指向全局对象window
定时器中,this指向调用对象的window- 构造函数中,this指向当前实例化对象
- 事件处理函数中,this指向事件
触发对象js中一般理解为谁调用就指向谁。
如何区分数组或对象
- 方法一 Array.isArray (是数组,true 否则为false)
- 方法二 instanceof (可以用来判断数组 是数组true 对象为false)
- 方法三 constructor ({}.constructor=>object [ ].constructor=>array)
- 方法四 Object.prototype.toString.call (object array/object object)