jsliang 的 2019 面试准备

Create by jsliang on 2019-2-11 15:30:34
Recently revised in 2019-3-17 21:30:36javascript

Hello 小伙伴们,若是以为本文还不错,记得给个 star , 小伙伴们的 star 是我持续更新的动力!GitHub 地址php


【2019-08-16】Hello 小伙伴们,因为 jsliang 对文档库进行了重构,这篇文章中的一些连接可能失效,而 jsliang 缺少精力维护掘金这边的旧文章,对此深感抱歉。请须要获取最新文章的小伙伴,点击上面的 GitHub 地址,去文档库查看调整后的文章。css


并非只有特定的季节才能跑路,只由于人跑得多了,这条路就定下来了。html

金三银四跳槽季,jsliang2019年2月11日 写下了这篇文章,开始准备本身的面试之旅。前端

2019年3月17日 为止,jsliang 搭建出我的的面试知识体系,海量地翻阅了一些前辈留下的资料,结合我的需求进行了几场面试,从而进一步完善该文章并进行了发表,但愿对准备跳槽或者正在跳槽中的小伙伴有所帮助。vue

一 目录

不折腾的前端,和咸鱼有什么区别java

目录
一 目录
二 前言
2.1 自我介绍
2.2 跳槽原委
2.3 进击目标
2.4 开篇点题
三 HTML
3.1 HTML 学习推荐
3.2 HTML 语义化
3.3 HTML5 新标签
3.4 常见浏览器及其内核
3.5 cookies、session、sessionStorage、localStorage
四 CSS
4.1 CSS 学习推荐
4.2 CSS reset
4.3 CSS 盒模型
4.4 CSS 单位
4.5 CSS 选择器
4.6 CSS 常见布局
4.7 CSS3 新特性
4.8 BFC
4.9 行内元素和块级元素
4.10 行内样式、内嵌式、连接式以及导入式
4.11 水平垂直居中
五 JavaScript
5.1 JS 学习推荐
5.2 JS 引用方式
5.3 原型与原型链
5.4 做用域与闭包
5.5 浅拷贝与深拷贝
5.6 模块化与组件化
5.7 面向对象与面向过程
5.8 防抖与节流
5.9 ES6
5.10 数组操做
六 Vue
6.1 MVVM
6.2 生命周期
6.3 双向数据绑定
6.4 Virtual DOM
6.5 template 编译
6.6 key
6.7 nextTick
6.8 父子组件通信
七 微信小程序
7.1 文件主要目录及文件做用
7.2 微信小程序生命周期
7.3 如何封装数据请求
7.4 页面数据传递
7.5 加载性能优化的方法
7.6 微信小程序与原生 APP、Vue、H5 差别
7.7 微信小程序原理
八 浏览器
8.1 浏览器解析 URL
8.2 重绘与回流
8.3 数据存储
8.4 内存管理与垃圾回收
8.5 内存泄漏
九 网络协议
9.1 网络分层
9.2 HTTP/HTTPS
9.3 HTTP 状态码
9.4 TCP 三次握手与四次挥手
十 性能优化
10.1 HTML 优化
10.2 CSS 优化
10.3 JavaScript 优化
十一 算法
十二 其余
十三 总结
十四 参考文献
14.1 关于面试
14.2 关于 HTML
14.3 关于 CSS
14.4 关于 JS
14.5 关于其余
十五 网友反馈

二 前言

返回目录css3

请时刻准备好本身的简历,无论是互联网经济不佳面临裁人,仍是由于公司内部斗争严重心乱如麻,仍是由于厌倦了目前的一切……只有随时更新本身,把本身的简历准备好,你才知道哪一刻跑路是最佳选择。git

2.1 自我介绍

返回目录es6

Hello 小伙伴们好,我叫梁峻荣,网名叫 jsliang,因为崇拜前端大佬 技术胖jspang)的缘由,又由于本身学的是前端(JavaScript),因此给本身取了个 jsliangJavaScriptLiang) 的网名,但愿本身能经过创建本身的前端知识体系,从而在前端路上走得更远。并将本身的经验分享给小伙伴,携手小伙伴们一块儿前行。

下面是讲讲我的故事:

首先jsliang 高考后的暑期就听大学师兄的建议,开始学习编程,那时候学习了 C 语言,以为世界上最神奇的事情不过如此,敲两下键盘,按下回车,电脑就会一闪一闪地响应咱们!因而在大学的时候,陆陆续续学过 C、C#、.Net 等……。

-_-|| 因为学得都是基础,又都还给老师了,在这里就很少累述了。

而后,在大二就开始接触 HTML,那时候选修了个《网页设计基础》,跟着老师作了个只有几个页面的静态网站。在大三的时候,参加了学校的特训班,分角色按流程从头至尾作了个包含角色管理、购物等功能的网站。同时,因为在特训班的时候,看到后端使用 ThinkPHP(简称 TP),以为蛮不错的,因而本身捣鼓,使用 TP 3.2.3 + Bootstrap 3 + MySQL 打造了本身的博客(已下线)。

接着,因为选修了门 Node.js 的课,因此也跟着大佬的步伐接触了下 Vue、Koa 这些,那时候对 npm 等诸多不懂,为了折腾这个,个人前端世界自此打开了个大门。

最后,我在本身的毕业设计中使用 Node.js + Vue + ElementUI + MongoDB 打造了个校园外卖、快递代拿等功能的社区单页应用。

在 2018 年 5 月的时候,家里催促,因而直接出来面试。不像其余大佬的毕业等于失业,很幸运地 jsliang 面试第一家就给了 offer,因而就进了这家公司,那时候感受本身前面的大学生活白过了,只懂 ES五、jQuery、HTML/HTML五、CSS/CSS3 的皮毛。

在熟悉了三个月的业务,公司给的任务能顺利完成后,我以为本身不够努力:外面的前端翻天覆地,个人技术却只是 jQuery is all!

因而 2018 年 8 月,jsliang 开始写 Markdown,将 5 月份到 8 月份记录到 Word 文档上的笔记整理成了 jsliang 的文档库,并在 jsliang 的掘金 上发表了第一篇文章。

18 年 8 月至今,jsliang 大体经历了如下这些:

  1. 学 Webpack,并用 Webpack 构建一个多页面配置。而后幸运的是,恰好碰到公司的一个仿站任务,因而整个前端小组直接用了个人 Webpack + jQuery + VS Code 的 Live Share 套路进行协同开发!
  2. 学 微信小程序,并将它应用到电信开发的微信小程序项目翼小微中。
  3. 学 ECharts 报表,并用它作了个 Vue + ECharts 的报表,来展现爱音乐公司的运营数据。
  4. 学 Node,而后搭了个企业网站(company.jsliang.top),并写了篇小文章(目前最高成就,得到了 1100 多赞)。
  5. 学 Vue,因为以前学的 Vue,在工做上有好多没有,逐渐淡忘了,因此从基础开始,准备写一套《Vue 从 0 到 1》。

以上,就是 jsliang 的编程生涯。

今儿,在这里写写 jsliang 为了跳槽,根据我的想法进行的一些前端面试资料整理,小伙伴们以为不错的点个赞或者去 GitHub 点个 star,以为有误请指出,谢谢~

2.2 跳槽原委

返回目录

马老板曾经说过,跳槽有两个缘由:

  1. 钱没给到位。
  2. 心被委屈了。

首先,若是非要给 jsliang 我本身的跳槽定个位,那确定是钱没给到位,劳动与产出不成正比。在我 2018 年 5 月入职前,与人事的交谈中了解到每一年的 8 月和 2 月能够提薪,当初的技术栈是:HTML、CSS、ES5。

而后,2018 年 6 月到 2019 年 1 月,学习并应用到工做中的技术有:

  1. jQuery
  2. Webpack
  3. JSP
  4. 微信小程序
  5. Vue
  6. ECharts

其中 2018 年 8 月刚转正,也不敢说本身技术进步很大,也不敢说本身项目贡献很大,为公司谋了多大利益,因此没有提薪想法。

2019 年 1 月底感受本身项目也作了,凌晨 4/5/6 点的体育西路也看过了,技术也提高了,因而跟人事交谈,指望 2 月能加薪,人事表示年终述职演讲得好的给提薪,2 月开工的时候表示提薪名单没我份……

你没看错,提薪全靠 PPT。PPT 里提升了不给,没提就是没有。
当初想法很简单,你随便加个 5/600 我也知足了。

最后jsliang 曾跟项目总监私下谈话,建议能够发展一些新产品,这样公司或许能获取一些新收入,我也能够进一步挑战个人技术。可是,因为我司是个老牌子公司,而且大部分依赖于接手电信项目进行扩张……

enm...因此心也委屈了。

在 2018 的努力下,GitHub 破 600 近 700 star,掘金破 10 万阅读量,3000 粉丝:
GitHub 见证:点击查看
掘金见证:点击查看

2.3 进击目标

返回目录

  • 目标城市:广州
  • 目标薪资:10K - 15K
  • 目标技术:
1. 熟悉 HTML/HTML五、CSS/CSS三、ES5/ES6。
2. 了解 OOP 概念,并尝试在工做中使用过 OOP 技巧。
3. 对 MVC/MVVM 架构有必定了解,若有 Vue/React/Angular 或者 微信小程序开发经验更佳。
4. 使用过 Bootstrap 或者 ElementUI 等 UI 库,并对前端 UI 库有必定的我的理解。
5. 了解 Git、Webpack 等工具。
6. 对 Java、Node.js 等后端编程有必定了解。
7. 一年及以上工做经验。
复制代码
  • 广州前端分析:
  1. 广州 13K 薪资要求:
    1. 2/3 年工做经验。
    2. 熟悉 OOP,并能在工做中使用,且能独立开发插件等……
    3. 你能够不懂 Vue,但 React 你必须得会!
  2. 广州 15k+ 薪资要求:
    1. 5 年+ 工做经验。
    2. 全能,懂前端,熟悉后端,能写文档……
    3. 带领太小队进行开发。
  3. 广州异常偏科公司:
    1. 要求必须懂后端。
    2. 要求必须懂安卓或者 IOS 开发。
    3. 要求必须精通 jQuery 全家桶(jQuery UI、jQuery Mobile 等……)。

该分析数据来自 Boss 直聘

2.4 开篇点题

返回目录

本文的知识点将涉及 HTML、CSS、JS、HTTP、Vue、Webpack、打包工具、性能优化等,没有前置条件,看得懂能够瞅瞅复习下,看不懂能够瞅瞅学习下。

关于面试,在这记下慕课网视频看到的,我的很是认同的三个问答:

  • 问:拿到一个面试题,第一时间看到什么? 答:考点
  • 问:如何看待网上搜出来的永远看不完的题海? 答:不变应万变
  • 问:如何对待面试题? 答:题目到知识再到题目

而后在复习面试题的过程当中,我的有些小见解:

  • 我的感言一:为何我老是比不上别人优秀?

当编写业务代码中,碰到某个业务 bug 时,我会习惯性地百度这个业务 bug,看看网友是怎么解决的。可是,学霸级的程序猿,会多走一步,他们会思考产生这个业务 bug 的底层缘由是什么,下次碰到相似的是如何应用该技术解决。因此,日积月累,个人确比不上人家了。

  • 我的感言二:辞职并非件便捷的事。

way 1:面试成功,跟本身公司递辞呈,走流程,同时跟对面 hr 申请一个月后入职。

way 2:面试成功,跟本身公司递辞呈,询问能不能快速离职,收到回复跟对面 hr 确认时间。【推荐】

way 3:先递辞呈,同时面试,面试成功的,一概申请走完原公司一个月的流程以后的日子入职。

jsliang 于 2 月底拿到 offer 并递交辞呈,3 月 - 4 月进入一个月倒计时,4 月第一周才能拿到离职证实。

最后在这里祝各位小伙伴能找到趁心如意的工做~

三 HTML

返回目录

HTML 属于结构层,负责描绘出内容的结构。

CSS 属于表示层,负责如何显示有关内容。

JavaScript 属于行为层,负责内容应如何对事件作出反应。

3.1 HTML 学习推荐

返回目录

3.2 HTML 语义化

返回目录

语义化的含义就是用正确的标签作正确的事情,HTML 语义化就是让页面的内容结构化,它有以下优势:

  1. 便于对浏览器、搜索引擎解析;
  2. 便于盲人浏览网页;
  3. 便于阅读源代码的人对网站进行分开,维护和理解;

简单来讲,能用 <header><footer> 等 H5 新标签的就不用 <div class="header">,不要使用 <div> 来存放段落等……

3.3 HTML5 新标签

返回目录

HTML5 中新增标签大体有:<header><footer><aside><nav><video><audio><canvas>等等。

3.4 常见浏览器及其内核

返回目录

Chrome Firefox Safari IE Opera
排版引擎 Blink Gecko Webkit Trident Blink
JS 引擎 V8 SpiderMonkey Nitro Chakra V8

国内一些浏览器使用较多的是 Webkit 内核。

  • 针对不一样浏览器内核,HTML 辨别:
  1. IE 内核浏览器识别:<!--[if IE]><![endif]-->
  2. 非 IE 内核浏览器识别:<!--[if !IE]><![endif]-->
  • 针对不一样浏览器内核,CSS 辨别:
/* 设置文字不可选取 */
* {
  -moz-user-select: none; /* 火狐 浏览器 */
  -webkit-user-select: none; /* Webkit 浏览器 */
  -o-user-select: none; /* Opera 浏览器 */
  -ms-user-select: none; /* IE10 浏览器 */
  -khtml-user-select: none; /* 早期浏览器 */
  user-select: none; /* 默认 */
}
复制代码

3.5 cookies、session、sessionStorage、localStorage

返回目录

  • cookies:存储于浏览器端的数据。能够设置 cookies 的到期时间,若是不设置时间,则在浏览器关闭窗口的时候会消失。

  • session:存储于服务器端的数据。session 存储特定用户会话所需的属性和配置信息。

  • cookiessession 的区别在于:

  1. cookies 数据存放在客户的浏览器上,session 数据存放在服务器上。
  2. 前端都是裸君子,没有安全可言,cookies 可能会被黑客利用做数据欺骗。因此重要信息记得存 session。
  3. session 若是在生效期内量过大,会占用服务器性能。
  4. 单个 cookies 保存的数据不能超过 4 K,不少浏览器限制一个站点保存最多 20 个 cookies。

  • sessionStorage:生命周期存在于标签页或窗口,用于本地存储一个会话(session)中的数据,这些数据会随着窗口或者标签页的关闭而被清空。

  • localStorage:生命周期是永久的,除非用户主动清除浏览器上存储的 localStorage 信息,不然它将会永久存在。

  • sessionStoragelocalStorage 操做方法:setItemgetItem 以及 removeItem

以 localStorage 为例:

localStorage.getItem('name'); // 获取 name 的值
localStorage.setItem('name', 'jsliang'); // 设置 name 的值为 jsliang
localStorage.removeItem('name'); // 删除 name 的值
复制代码

参考 1:《前端分享之cookie的使用及单点登陆》
参考 2:《Cookie、session和localStorage、以及sessionStorage之间的区别》

四 CSS

返回目录

HTML 属于结构层,负责描绘出内容的结构。

CSS 属于表示层,负责如何显示有关内容。

JavaScript 属于行为层,负责内容应如何对事件作出反应。

4.1 CSS 学习推荐

返回目录

4.2 CSS reset

返回目录

在工做的过程当中,会发现各式各样的浏览器对某个标签有本身独特的样式。

可是在前端开发中,若是不采用统一标准,那么会产生千奇百怪的 bug。因此为了减小后期 bug 的出现,前端开发人员会重置一遍 CSS 样式,尽量地使开发的网页在各个浏览器相差不大。

下面是 jsliang 在使用的样式重置,固然若是小伙伴有不一样的想法,能够去 百度/必应/google 搜索并使用其余版本的样式重置:

4.3 CSS 盒模型

返回目录

在工做的过程当中,也许小伙伴须要 div 块的总宽度为 100px,而后发现老是被 margin 撑高,这是由于盒模型定义的问题:

CSS 中有个属性叫 box-sizing

box-sizing: border-box
box-sizing: content-box
复制代码
  1. border-box 中,整个 div 的宽、高,包括 marginpaddingborder
  2. content-box 中,整个 div 的宽、高,则不包括上面元素。

如上图,若是一个 div ,你的代码以下:

div {
  box-sizing: border-box;
  margin: 10px;
  width: 100px;
  height: 100px;
  padding: 10px;
}
复制代码

那么,你的整个宽高仍是 100px

可是,若是你的代码以下:

div {
  box-sizing: content-box;
  margin: 10px;
  width: 100px;
  height: 100px;
  padding: 10px;
}
复制代码

那么,你的整个盒子宽高是 120px

若是你在设计页面中,发现内容区被撑爆了,那么,请检查下如今的 border-box 是什么,最好在引用 reset.css 的时候,就对 border-box 进行统一设置,方便管理。

4.4 CSS 单位

返回目录

在 CSS 中,除了咱们经常使用的 px,还有其余单位小伙伴们能够了解一下:

单位 描述
% 百分比
px 像素。计算机屏幕上的一个点为 1px
em 相对单位。相对于父元素计算,假如某个 p 元素为 font-size: 12px,在它内部有个 span 标签,设置 font-size: 2em,那么,这时候的 span 字体大小为:12 * 2 = 24px
rem 相对单位。相对于根元素 html 的 font-size,假如 html 为 font-size: 12px,那么,在其当中的 div 设置为 font-size: 2rem,就是当中的 div 为 24px
rpx 微信小程序相对单位。1rpx = 屏幕宽度 / 750 px。在 750px 的设计稿上,1rpx = 1px。

除此以外还有 pt、ex 等单位,但因为不太好换算,故在此不提。

4.5 CSS 选择器

返回目录

选择器是匹配元素的一种模式。

  • 关于 CSS 解析器:

HTML 通过解析生成 DOM Tree;而在 CSS 解析完毕后,须要将解析的结果与 DOM Tree 的内容一块儿进行分析创建一棵 Render Tree,最终用来进行绘图。

Render Tree 中的元素与 DOM 元素相对应,但非一一对应:一个 DOM 元素可能会对应多个 renderer,如文本折行后,不一样的「行」会成为 render tree 种不一样的 renderer。也有的 DOM 元素被 Render Tree 彻底无视,好比 display:none 的元素。

在创建 Render Tree 时,浏览器就要为每一个 DOM Tree 中的元素根据 CSS 的解析结果来肯定生成怎样的 renderer。对于每一个 DOM 元素,必须在全部 Style Rules 中找到符合的 selector 并将对应的规则进行合并。选择器的「解析」实际是在这里执行的,在遍历 DOM Tree 时,从 Style Rules 中去寻找对应的 selector。

  • CSS 解析顺序

在 CSS 的选择器中,它会按照优先级 从右向左解析,由于这样匹配元素的时候,能尽可能少地查找,因此选择器最好写地简洁一点。

  • CSS 经常使用选择器
  1. 通配符:*
  2. ID 选择器:#ID
  3. 类选择器:.class
  4. 元素选择器:pa 等……
  5. 后代选择器:p spandiv a 等……
  6. 伪类选择器:a:hover 等……
  7. 属性选择器:input[type="text"] 等……
  8. 子元素选择器:li:firth-childp:nth-child(1) 等……
  • CSS 选择器权重

!important -> 行内样式 -> #id -> .class -> 元素和伪元素 -> * -> 继承 -> 默认

4.6 CSS 常见布局

返回目录

  1. 水平垂直居中。这种布局老生常谈,jsliang 在本文也有提到,详解请 点击连接
  2. 两列布局。一侧固定,另外一侧自适应。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Two Column Layout</title>
  <style> .container { display: flex; } .child-one { width: 300px; height: 300px; background: red; } .child-two { width: 100%; height: 300px; background: deepskyblue; } </style>
</head>
<body>
  <div class="container">
    <div class="child-one"></div>
    <div class="child-two"></div>
  </div>
</body>
</html>
复制代码
  1. 三列布局。相似于两列布局,新增多一个固定宽的 <div> 块而已。固然,小伙伴们可能会说:jsliang 你要考虑 flex 的兼容性啊!enm...支持全部最新版本的浏览器!请更新你的浏览器哦亲~

避免被寄刀片,附上 float 布局:《css常见布局》

4.7 CSS3 新特性

返回目录

经典:CSS3 相关属性你了解吗,说说都有哪些?能说说你工做中经常使用的一些 CSS3 属性吗?

那么,CSS3 新特性都有哪些呢?

  • transition:过渡
  • transform:旋转、缩放、移动或者倾斜
  • animation:动画
  • gradient:渐变
  • shadow:阴影
  • border-radius:圆角

为了方便记忆,咱将它们扔到同一个 HTML 文件上,小伙伴拷贝到本地上打开,能够看到一个拥有渐变的小球,作着横向运动,若是你鼠标移动到它上面,它的宽度会放大,而且进行倾斜。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>CSS3 新特性</title>
<style> div { width: 100px; height: 100px; border-radius: 50px; background: linear-gradient(red, orange); box-shadow: 10px 10px 5px #888888; position: relative; transition: width 2s; animation: mymove 5s infinite; } div:hover { width:300px; transform: rotate(7deg); } @keyframes mymove { from { left: 0px; } to { left: 200px; } } </style>
</head>
<body>
  <div></div>
</body>
</html>
复制代码

参考 1:《CSS3 圆角》
参考 2:《CSS3 渐变(Gradients)》
参考 3:《CSS3 transition 属性》
参考 4:《CSS3 transform 属性》
参考 5:《CSS3 animation(动画) 属性》
参考 6:《CSS3 box-shadow 属性》
参考 7:《我的总结(css3新特性)》

4.8 BFC

返回目录

  • 什么是 BFC?

BFC 就是 块级格式上下文,它是一个独立的渲染区域,让处于 BFC 内部的元素和外部的元素相互隔离,使内外元素的定位不会相互影响。

必定的 CSS 声明能够生成 BFC,浏览器对生成的 BFC 有一系列的渲染规则,利用这些渲染规则能够达到必定的布局效果。

  • 为何须要 BFC 呢?
  1. 它能够防止 margin 元素重叠(div 中包含 ul,而 div 与 ul 之间的垂直距离,取决于 div、ul、li 三者之间的最大外边距,这时候给 ul 一个 display:inline-block 便可解决这个问题)
  2. 清除内部浮动(div 中包含 ul,而 ul 采用 float:left,那么 div 将变成一长条,这时候给 div 加上规则使其变成 BFC 便可)
  • 如何产生 BFC?
  1. display: inline-block
  2. position: absolute/fixed
  • 工做中通常可能不会顾及这个:
  1. float 不多使用了,尽量使用 flex
  2. css reset 通常会清除掉一些问题,减小 BFC 的使用。

参考文献:《我对BFC的理解》

返回目录

4.9 行内元素和块级元素

返回目录

行内元素:宽度和高度由内容决定,与其余元素共占一行的元素,咱们将其叫行内元素。例如:<span><i><a> 等……

块级元素:默认宽度由父容器决定,默认高度由内容决定,独占一行而且能够设置宽高的元素,咱们将其叫作块级元素。例如:<p><div><ul> 等……

在平常开发中,咱们常用 CSS 的 display 属性来打破二者的壁垒:display: inline-block,使它们拥有更多的状态。

4.10 行内样式、内嵌式、连接式以及导入式

返回目录

在引用 CSS 上,分为四种形式:行内样式内嵌式连接式以及导入式,下面介绍这四种模式。

  • 行内样式

直接对 HTML 的标记使用 style 属性,而后将 CSS 代码直接写进去:

<p style="color: #fff; backgournd: deepskyblue;"></p>
复制代码
  • 内嵌式

将 CSS 写 <head></head> 之间,而且用 <style></style> 标记进行声明:

<head>
  <style> p { color: #fff; background: deepskyblue; } </style>
</head>
复制代码
  • 连接式

经过将 <style> 上的 CSS 提起到指定的 CSS 文件上,而后经过 <link> 的方式在 HTML 上连接起来。

<head>
  <link href="reset.css" type="text/css" rel="stylesheet">
</head>
复制代码
  • 导入样式
<head>
  <style> @import url(reset.css); </style>
</head>
复制代码
  • 各类方式的优先级

在优先级上,行内样式 > 连接式 > 内嵌式 > @import 导入式

4.11 水平垂直居中

返回目录

  • 什么是 Flex 布局?

Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

  • Flex 布局有哪些便利
/* 设置 Flex 模式 */
display: flex;

/* 决定元素是横排仍是竖着排,要不要倒序 */
flex-direction: column;

/* 决定元素换行格式,一行排不下的时候如何排 */
flex-wrap: wrap;

/* flex-flow = flex-direction + flex-wrap */
flex-flow: column wrap;

/* 同一排下对齐方式,空格如何隔开各个元素 */
justify-content: space-between;

/* 同一排下元素如何对齐,顶部对齐、中部对齐仍是其余 */
align-items: center;

/* 多行对齐方式 */
align-content: space-between;
复制代码
  • 如何经过 Flex 实现元素水平垂直居中?

HTML

<div class="container">
  <div class="child"></div>
</div>
复制代码

CSS

.container {
  margin: 0 auto;
  width: 300px;
  height: 200px;
  background: deepskyblue;
  display: flex;
  /* 实现元素水平居中 */
  justify-content: center;
  /* 实现元素垂直居中 */
  align-items: center;
}
.child {
  width: 100px;
  height: 100px;
  background: #fff;
}
复制代码
  • 除了 Flex,还能使用其余形式进行水平垂直居中吗?

HTML

<div class="container">
  <div class="child"></div>
</div>
复制代码

CSS

.container {
  position: relative;
  width: 300px;
  height: 200px;
  background: pink;
  margin: 0 auto;
}
.child {
  position: absolute;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  /* 下面两种方式都可 */
  /* margin-top: -50px;
  margin-left: -50px; */
  transform: translate(-50%, -50%);
  background: #fff;
}
复制代码
  • 除此以外再谈谈 CSS 水平居中或者垂直居中?

水平居中:

  1. 行内元素:display: inline-block; text-align: center;
  2. 块级元素:margin: 0 auto;
  3. Flex:display: flex; justify-content: center;

垂直居中:

  1. 行高 = 元素高:line-height: height
  2. Flex:display: flex; align-items: center;

参考文献:
《CSS实现垂直居中的经常使用方法》
《CSS 用 position: absolute 与 transform 来居中块级元素的问题》

五 JavaScript

返回目录

HTML 属于结构层,负责描绘出内容的结构。

CSS 属于表示层,负责如何显示有关内容。

JavaScript 属于行为层,负责内容应如何对事件作出反应。

5.1 JS 学习推荐

返回目录

  • 《JavaScript 高级程序(第三版)》
  • 《你不知道的 JavaScript》
  • 《JavaScript 忍者秘籍》
  • 《ES6 标准入门》—— 阮一峰
  • 《JavaScript 设计模式》—— 张容铭
  • 《JavaScript 设计模式与开发实践》—— 曾探

5.2 JS 引用方式

返回目录

  • 行内引入
<body>
  <input type="button" onclick="alert('行内引入')" value="按钮"/>
  <button onclick="alert(123)">点击我</button>
</body>
复制代码
  • 内部引入
<script> window.onload = function() { alert("js 内部引入!"); } </script>
复制代码
  • 外部引入
<body>
  <div></div>

  <script type="text/javascript" src="./js/index.js"></script>
</body>
复制代码

注意

  1. 不推荐写行内或者在 HTML 中插入 <script>,由于浏览器解析顺序缘故,若是解析到死循环之类的 JS 代码,会卡住页面。
  2. 建议在 onload 事件以后,即等 HTML、CSS 渲染完毕再执行代码。

5.3 原型与原型链

返回目录

关于 prototype__proto__newcall()apply()bind()this 这些的知识点,因为篇幅太长,jsliang 已经抽离了出来,并作了简洁详细讲解,详见:

下面放出相关知识点:

  • 实例的 __proto__ 属性(原型)等于其构造函数的 prototype 属性。
  • Object.proto === Function.prototype
  • Function.prototype.proto === Object.prototype
  • Object.prototype.proto === null

5.4 做用域与闭包

返回目录

在 JS 中,最容易混淆的就是做用域的状况。

在传统的后端语言(例如 C 语言)中,一对花括号 {} 就是一个块级做用域,做用域内变量不会相互影响,可是在 JS 中,像 if 条件语句的 {} 就不算一个独立的做用域:

var x = 1;
console.log(x); // 1
if(true) {
  var x = 2;
  console.log(x); // 2
}
console.log(x); // 2
复制代码

因此有时候咱们就须要变通,经过自执行函数建立临时做用域:

function foo() {
  var x = 1;
  console.log(x); // 1
  if(x) {
    (function(x) {
      console.log(x); // 1
      var x = 2;
      console.log(x); // 2
    })(x)
  }
  console.log(x); // 1
}
foo();
复制代码

说到建立临时做用域,咱们就不得不谈一下闭包。

那么,什么是闭包呢?

闭包简单定义:函数 A 里面包含了 函数 B,而 函数 B 里面使用了 函数 A 的变量,那么 函数 B 被称为闭包。

又或者:闭包就是可以读取其余函数内部变量的函数

function A() {
  var a = 1;
  function B() {
    console.log(a);
  }
  return B();
}
复制代码
  • 闭包经典问题:如今咱们有一段代码:
for(var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
复制代码

请问这段代码输出什么?

答案:3 个 3。
解析:首先,for 循环是同步代码,先执行三遍 for,i 变成了 3;而后,再执行异步代码 setTimeout,这时候输出的 i,只能是 3 个 3 了。

  • 那么,咱们有什么办法依次输出 0 1 2 么?
  1. 使用 let:
for(let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
复制代码

在这里,每一个 let 和代码块结合起来造成块级做用域,当 setTimeout() 打印时,会寻找最近的块级做用域中的 i,因此依次打印出 0 1 2。

若是这样讲不明白,咱们能够执行下下面这段代码:

for(let i = 0; i < 3; i++) {
  console.log("定时器外部:" + i);
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
复制代码

此时浏览器依次输出的是:

定时器外部:0
定时器外部:1
定时器外部:2
0
1
2
复制代码

即代码仍是先执行 for 循环,可是当 for 结束执行到了 setTimeout 的时候,它会作个标记,这样到了 console.log(i) 中,i 就能找到这个块中最近的变量定义。

  1. 使用当即执行函数解决闭包问题
for(let i = 0; i < 3; i++) {
  (function(i){
    setTimeout(function() {
      console.log(i);
    }, 1000);
  })(i)
}
复制代码

以上,咱们就讲解完了闭包及解决闭包的方式。

观点 1:有些资料表示闭包中产生的大量局部变量,会形成内存消耗过大,从而形成网页的性能问题。
观点 2:有些资料表示目前浏览器引擎都基于 V8,而 V8 引擎有个 gc 回收机制,不用太过担忧变量不会被回收。
提示:因此,若是你以为不够保险,那就在退出函数以前,将不使用的局部变量所有删除。

5.5 浅拷贝与深拷贝

返回目录

  • 什么是深拷贝?什么是浅拷贝?

简单来讲,有两个对象 A 和 B,B = A,当你修改 A 时,B 的值也跟着发生了变化,这时候就叫浅拷贝。若是不发生变化,就叫深拷贝。

  • 为何会出现深拷贝与浅拷贝?
  1. 首先咱们须要知道基本数据类型(number、string、boolean、null、undefined)引用数据类型(无序对象,数据以及函数)
  2. 而后在基本数据类型中,例如:let a = 1; let b = a; a = 2; console.log(b)。当咱们尝试这样子写时,b 在栈内存中开辟了一个新内存,因此 b 的值不会改变,还是 1.
  3. 接着在引用数据类型中,例如 let a = [1, 2, 3], b = a; a[0] = 3; console.log(b)。当咱们尝试这样子写时,b 会偷懒,引用跟 a 同一块的内存地址,从而 a 的修改会影响 b,使得 b 变成 [3, 1, 3]。
  4. 最后,咱们能够知道在引用数据类型中,会产生浅拷贝的问题。
  • 如何实现深拷贝?
  1. 首先咱们尝试使用递归去解决深拷贝:
function deepClone(obj) {
  let objClone = Array.isArray(obj) ? [] : {};
  if(obj && typeof obj === "object") {
    for(key in obj) {
      if(obj.hasOwnProperty(key)) {
        // 判断 obj 子元素是否为对象,若是是,递归复制
        if(obj[key] && typeof obj[key] === "object") {
          objClone[key] = deepClone(obj[key]);
        } else {
          // 若是不是,简单复制
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}

let a = [1, 2, 3, 4];
let b = deepClone(a);
a[0] = 2;
console.log(a, b);

// Console
// a = [2, 2, 3, 4];
// b = [1, 2, 3, 4];
复制代码
  1. 使用 JSON 对象的 parse 和 stringify

注意:采用 JSON 进行的深拷贝,没法拷贝到 undefined、function、symbol 这类数据,它是有小 bug 的深拷贝。

function deepClone(obj) {
 let _obj = JSON.stringify(obj);
 let objClone = JSON.parse(_obj);
 return objClone
}
let a = [0, 1, [2, 3], 4];
let b = deepClone(a);
a[0] = 1;
a[2][0] = 1;
console.log(a, b);

// Console
// a = [1, 1, [1, 3], 4];
// b = [0, 1, [2, 3], 4];
复制代码

5.6 模块化与组件化

返回目录

在前端发展中,随着先后端分离,前端社区的不断壮大,前端能作的事情愈来愈多,承受的任务愈来愈重,代码也就愈来愈长了。就比如 jsliang 我的使用 jQuery 开发的时候,动不动就上千行代码,这在一个编辑器上看起来就有点乱了。若是碰上没有代码折叠的编辑器,你就更加难受了。

有的小伙伴的编辑器不是 VS Code,也不能进行代码折叠

因此,面对愈来愈多的代码,咱们就急需将这些代码分门别类,将代码按功能划分,将同一功能的代码整合在一块儿,因而就有了模块化开发:一个文件就是一个模块,当咱们须要某个文件的时候,咱们只须要引用这个模块便可……

首先,是 CommonJS 的提出,在 Node.js 以及 Webpack 都支持 CommonJS,它规定了一个文件就是一个模块,文件内部定义的变量属于这个模块,不会对外暴露从而污染全局变量的规则。在 CommonJS 中,经过 exports 或者 module.exports 进行导出,经过 require 进行 同步加载 所须要依赖的模块。因为它是同步加载模块的形式,因此比较通用于服务器端。

而后,根据 CommonJS 只能同步加载的问题,AMD 根据浏览器的特性,进行了非同步加载模块的提出。同时,AMD 有个问题,就是在使用 require.js 的时候,必须提早加载全部模块。

接着,根据 AMD 的问题,CMD 提出来了:经过按需加载的形式,哪里须要就调用哪里,而不用等到全部的模块都加载了再解析。

最后,ECMA 国际推出了 ES6 的 modules。在 ES6 中,经过 export 关键字导出模块,经过 import 关键字引用代码。固然,因为浏览器厂商诸多,ES6 在浏览器的尚不支持,目前主流作法是先将 ES6 经过 babel 编译成 require。

固然,JS 都进行模块化了,jsliang 想起本身项目中的那一坨 CSS,真心没有回顾的想法!因此咱们还须要知道为了方便管理 CSS,大佬们仍是有作事儿的:Less 以及 Sass,这二者使 CSS 的编写更有组织性和目的性了。

提及模块化,咱们又能够顺带说起组件化了,一开始为了区分这二者,jsliang 也是百度了大量文章,最后成功把本身整蒙了,仍是说说感受能够的解释:

组件化更关注的是 UI 部分:弹出框、头部,内容区、按钮等,均可以编写成组件,而后在适用的地方进行引用。而模块化更侧重于功能或者数据的封装,好比全局的 JSON 配置文件,好比通用的验证方法,好比规范时间戳等。

因此,说到这里,咱们就能够提到前端工程化:将整个开发流程就行工程规划,从而提升整个团队的开发效率。

在前端工程化中,最重要的就是提升整个团队在 编码 -> 测试 -> 维护 这三个阶段的生产效率。团队的协调相当重要,将每一个任务细分给各个成员,从而获取极致的工做效率,是管理者最喜欢看到的。而在上面的模块化和组件化的应用,就属于前端工程化中的一部分,其目的就是在一些复杂的项目中,方便团队进行合做开发,提升生产效率。

参考文献:
《到底什么是前端工程化、模块化、组件化》
《【前端工程化系列】简谈前端模块化开发与开发规范》
《我的关于模块化的理解》
《组件化开发和模块化开发概念辨析》
《JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules》
《浅谈什么是前端工程化》

5.7 面向对象与面向过程

返回目录

  1. 什么是面向过程与面向对象?
  • 面向过程就是作围墙的时候,由你自己操做,叠第一层的时候:放砖头,糊水泥,放砖头,糊水泥;而后第二层的时候,继续放砖头,糊水泥,放砖头,糊水泥……
  • 面向对象就是作围墙的时候,由他人帮你完成,将作第一层的作法抽取出来,就是放砖头是第一个动做,糊水泥是第二个动做,而后给这两个动做加上步数,最后告诉机器人有 n 层,交给机器人帮你工做就好了。
  1. 为何须要面向对象写法?
  • 更方便
  • 能够复用,减小代码冗余度
  • 高内聚低耦合

简单来讲,就是增长代码的可复用性,减小我们的工做,使代码更加流畅。

  1. 手写个面向对象代码?
function Person(name, phone) {
  this.name = name;
  this.phone = phone;
  this.eat = function() {
    console.log(name + " 吃饭");
  }

  return this;
}

let p1 = new Person("jsliang", "18818881888");
console.log(p1.name); // jsliang
p1.eat(); // jsliang 吃饭
复制代码

固然,jsliang 只能写到这里了,再写下去就是设计模式等知识点了。

因此但愿小伙伴们仍是了解下面向对象思想,有助于进一步提高本身。

5.8 防抖与节流

返回目录

关于 防抖与节流jsliang 特地将资料结合起来:

  • 防抖与节流
  • 重绘与回流
  • 浏览器解析 URL
  • DNS 域名解析
  • TCP 三次握手与四次挥手
  • 浏览器渲染页面

小伙伴们能够前往 《面试知识点 - JS 防抖与节流》 查看。

5.9 ES6

返回目录

ES6 是个大知识点,若是你面试的公司不是 “饱经沧桑” 的那种,那么必定会出点 ES6 问题,例如:

  • 说说 let、var、const 区别
  • 讲讲 Promise 及其使用

由于 jsliang 感受本身连 ES6 的门还没进,因此在这里就不 自做聪明,推荐下阮一峰大佬的教程:

但愿小伙伴们看完能有所收获,并在工做中大量使用。

5.10 数组操做

返回目录

在 JavaScript 中,用得较多的之一无疑是数组操做,这里过一遍数组的一些用法:

  • map: 遍历数组,返回回调返回值组成的新数组
  • forEach: 没法break,能够用try/catch中throw new Error来中止
  • filter: 过滤
  • some: 有一项返回true,则总体为true
  • every: 有一项返回false,则总体为false
  • join: 经过指定链接符生成字符串
  • push / pop: 末尾推入和弹出,改变原数组, 返回推入/弹出项【有误】
  • unshift / shift: 头部推入和弹出,改变原数组,返回操做项【有误】
  • sort(fn) / reverse: 排序与反转,改变原数组
  • concat: 链接数组,不影响原数组, 浅拷贝
  • slice(start, end): 返回截断后的新数组,不改变原数组
  • splice(start, number, value...): 返回删除元素组成的数组,value 为插入项,改变原数组
  • indexOf / lastIndexOf(value, fromIndex): 查找数组项,返回对应的下标
  • reduce / reduceRight(fn(prev, cur), defaultPrev): 两两执行,prev 为上次化简函数的return值,cur 为当前值(从第二项开始)

相信小伙伴在工做中耍的已是一套一套的了,或者像 jsliang 同样只会简单的使用 pushmap 这几个,感兴趣的小伙伴能够 百度/bing/google 找找一些 奇技淫巧,说不定对工做效率有很大提高~

六 Vue

返回目录

推荐:

  1. 技术胖
  2. 慕课网

6.1 MVVM

返回目录

在 MVVM 架构下,View 和 Model 之间并无直接的联系,而是经过 ViewModel 进行交互,Model 和 ViewModel 之间的交互时双向的,所以 View 数据会同步到 Model 中,而 Model 数据的变化也会当即反应到 View 上。

ViewModel 经过双向数据绑定把 View 层和 Model 层链接了起来,而 View 和 Model 之间的同步工做彻底是自动的,无需人为干涉,所以开发者只须要关注业务逻辑,不须要手动操做 DOM,不须要关注数据状态的同步问题,复杂的数据状态维护彻底由 MVVM 来统一管理。

  1. M - Model。Model 表明数据模型,也能够在 Model 中定义数据修改和操做的业务逻辑。
  2. V - View。View 表明 UI 组件,它负责将数据模型转化为 UI 展示出来。
  3. VM - ViewModel。ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步 View 和 Model 的对象,链接 Model 和 View。

6.2 生命周期

返回目录

  • 请大体讲下 Vue 的生命周期?
  1. 建立前/后:在 beforeCreated 阶段,Vue 实例的挂载元素 $el 和数据对象 data 以及事件还未初始化。在 created 阶段,Vue 实例的数据对象 data 以及方法的运算有了,$el 尚未。
  2. 载入前/后:在 beforeMount 阶段,render 函数首次被调用,Vue 实例的 $el 和 data 都初始化了,但仍是挂载在虚拟的 DOM 节点上。在 mounted 阶段,Vue 实例挂载到实际的 DOM 操做完成,通常在该过程进行 Ajax 交互。
  3. 更新前/后:在数据更新以前调用,即发生在虚拟 DOM 从新渲染和打补丁以前,调用 beforeUpdate。在虚拟 DOM 从新渲染和打补丁以后,会触发 updated 方法。
  4. 销毁前/后:在执行实例销毁以前调用 beforeDestory,此时实例仍然能够调用。在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 Vue 实例已经解除了事件监听以及和 DOM 的绑定,可是 DOM 结构依然存在。
  • 什么是 Vue 生命周期?

Vue 实例从建立到销毁的过程,就是生命周期。从开始建立、初始化数据、编译模板、挂载 DOM -> 渲染、更新 -> 渲染、销毁等一系列过程,称之为 Vue 的生命周期。

  • Vue 有几个生命周期,它们的做用主要是什么?

8 个,建立前/建立后、挂载前/挂载后、更新前/更新后、销毁前/销毁后。Vue 生命周期的做用是方便咱们经过它的生命周期,在业务代码中更好地操做数据,实现相关功能。

  • 第一次页面加载会触发 Vue 哪几个钩子?

会触发 4 个生命钩子:建立前/建立后、挂载前/挂载后

  • DOM 渲染在哪一个周期就已经完成?

beforeMounted 时它执行了 render 函数,对 $el 和 data 进行了初始化,但此时仍是挂载到虚拟的 DOM 节点,而后它在 mounted 时就完成了 DOM 渲染,这时候咱们通常还进行 Ajax 交互。

6.3 双向数据绑定

返回目录

Vue 采用 数据劫持 结合 发布者-订阅者 模式的方式,经过 Object.defineProperty() 来劫持各个属性的 setter 以及 getter,在数据变更时发布消息给订阅者,触发相应的监听回调。

  1. 第一步:须要 Observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
  2. 第二步:Compile 解析模板指令,将模板中的变量替换成数据,而后初始化渲染页面视图,并将每一个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变更,收到通知,更新数据。
  3. 第三步:Watcher 订阅者是 Observer 和 Compile 之间通讯的桥梁,主要作的事情有:
    1. 在自身实例化时往属性订阅器(dep)里面添加本身。
    2. 自身必须有一个 update() 方法
    3. 待属性变更 dep.notice() 通知时,能调用自身的 update() 方法,并触发 Compile 中绑定的回调,则功成身退。
  4. 第四步:MVVM 做为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,经过 Observer 来监听本身的 model 数据变化,经过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据 model 变动的双向绑定效果。

js 实现简单的双向绑定

<body>
  <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
  </div>
  
  <script>
    window.onload = function() {
      let obj = {};
      Object.defineProperty(obj, "txt", {
        get: function() {
          return obj;
        },
        set: function(newValue) {
          document.getElementById("txt").value = newValue;
          document.getElementById("show").innerHTML  = newValue;
        }
      })
      document.addEventListener("keyup", function(e) {
        obj.txt = e.target.value;
      })
    }
  </script>
</body>
复制代码

Object.defineProperty 接收三个参数:对象,属性名,配置对象
这里使用的是 Object.defineProperty,这是 Vue 2.0 进行双向数据绑定的写法。在 Vue 3.0 中,它使用 Proxy 进行数据劫持。

  • 为何 Vue 3.0 中使用 Proxy 了?
  1. Vue 中使用 Object.defineProperty 进行双向数据绑定时,告知使用者是能够监听数组的,可是只是监听了数组的 push()、pop()、shift()、unshift()、splice()、sort()、reverse() 这八种方法,其余数组的属性检测不到。
  2. Object.defineProperty 只能劫持对象的属性,所以对每一个对象的属性进行遍历时,若是属性值也是对象须要深度遍历,那么就比较麻烦了,因此在比较 Proxy 能完整劫持对象的对比下,选择 Proxy。
  3. 为何 Proxy 在 Vue 2.0 编写的时候出来了,尤大却没有用上去?由于当时 es6 环境不够成熟,兼容性很差,尤为是这个属性没法用 polyfill 来兼容。(polyfill 是一个 js 库,专门用来处理 js 的兼容性问题-js 修补器)

参考自《实现双向绑定Proxy比defineproperty优劣如何》

6.4 Virtual DOM

返回目录

Vue 在 rendercreateElement 的时候,并非产生真实的 DOM 元素,实际上 createElement 描述为 createNodeDescription,由于它所包含的信息会告诉 Vue 页面上须要渲染什么样的节点。

所以,咱们将这样的节点描述为 “虚拟节点”(Virtual Node),简称 VNode。“虚拟 DOM” 是咱们对由 Vue 组件树创建的整个 VNode 树的称呼。

做为一枚切图仔,很荣幸地跟小伙伴说:“其实我也不懂 Virtual DOM!”

可是,总会有些面试场合会提到的,因此这里找了几篇资料,小伙伴们能够进一步学习:

其余的就须要小伙伴本身寻找了,若是以为有不错的解析 Virtual DOM 的文档/视频,小伙伴也能够推荐过来哈~

6.5 template 编译

返回目录

  • Vue template 编译的理解

Vue 中 template 就是先转化成 AST 树,再获得 render 函数返回 VNode(Vue 的虚拟 DOM 节点)。

  1. 经过 compile 编译器把 template 编译成 AST 语法树(abstract syntax tree - 源代码的抽象语法结构的树状表现形式),compile 是 createCompiler 的返回值,createCompiler 是用以建立编译器的。另外 compile 还负责合并 option。
  2. AST 会通过 generate(将 AST 语法树转换成 render function 字符串的过程)获得 render 函数,render 的返回值是 VNode,VNode 是 Vue 的虚拟 DOM 节点,里面有标签名、子节点、文本等待。

6.6 key

返回目录

key 的做用就是在更新组件时判断两个节点是否相同。相同就复用,不相同就删除旧的建立新的。

对于 diff 过程来讲 key 是起不到提速做用的,详见:key 的做用

6.7 nextTick

返回目录

  • 用法:Vue.nextTick( [callback, context] )

  • 参数:

    • {Function} [callback]
    • {Object} [context]
  • 说明:在下次 DOM 更新循环结束以后执行延迟回调。在修改数据以后当即使用这个方法,获取更新后的 DOM。

  • 案例:

// 修改数据
vm.msg = 'Hello'
// DOM 尚未更新
Vue.nextTick(function () {
  // DOM 更新了
})

// 做为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
Vue.nextTick().then(function () {
  // DOM 更新了
})
复制代码

关于 nextTick 的更多理解,jsliang 就不献丑了,须要学习的小伙伴能够查看:

或者自行查找更优秀的资源。

6.8 父子组件通信

返回目录

关于 Vue 中的父子组件通信,相信常常开发 Vue 的小伙伴比 jsliang 知道的多不少。

没怎么使用 Vue 的小伙伴能够看下下面的文章,并尝试本身写一写:

下面咱讲下使用 bus.js 实现非父子组件通信:

假设在工做中,有三个 .vue 文件:A.vue、B.vue、C.vue。A.vue 是主页面,B.vue 和 C.vue 相似于头部导航条和底部导航栏。如今,B.vue 点击会切换路由,C.vue 须要获取 B.vue 传递的信息。

A.vue

<template>
  <div>
    <top-nav></top-nav>
    <div class="container">
      <router-view></router-view>
    </div>
    <bottom-nav></bottom-nav>
  </div>
</template>
复制代码

bus.js

import Vue from 'vue';

// 使用 Event Bus
const bus = new Vue();

export default bus;
复制代码

B.vue

<template>
  <div class="bottom-nav">
    <div class="nav-one" @click="goToPage({path: '/HomeIndex', meta:'首页'})">
      <i class="icon-home"></i>
      <span>首页</span>
    </div>
  </div>
</template>

<script> import bus from '../utils/bus' export default { methods: { goToPage(route) { this.$router.push(route.path); bus.$emit('meta', route.meta); } } } </script>
复制代码

C.vue

<template>
  <div class="top-nav">
    <span class="title">{{title}}</span>
  </div>
</template>

<script> import bus from '../utils/bus' export default { data() { return { title: '' } }, created() { bus.$on('meta', msg=> { this.title = msg; }) } } </script>
复制代码

七 微信小程序

返回目录

微信小程序,简称小程序,英文名 Mini Program,是一种不须要下载安装便可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下便可打开应用。

7.1 文件主要目录及文件做用

返回目录

- component —————————————————— 组件文件夹
  - navBar                  —— 底部组件
    - navBar.js             —— 底部组件的 JS 代码
    - navBar.json           —— 底部组件的配置文件
    - navBar.wxml           —— 底部组件的 HTML 代码
    - navBar.wxss           —— 底部组件的 CSS 代码
- pages  ————————————————————— 页面文件夹
  - index                   —— 首页
    - index.js              —— 首页的 JS 代码
    - index.json            —— 首页的配置文件
    - index.wxml            —— 首页的 HTML 代码
    - index.wxss            —— 首页的 CSS 代码
- public ————————————————————— 图片文件夹
- utils —————————————————————— 工具文件夹
  - api.js                  —— 控制 API 的文件
  - md5.js                  —— 工具 - MD5 加密文件
  - timestamp.js            —— 工具 - 时间戳文件
- app.json ——————————————————— 设置全局的基础数据等
- app.wxss ——————————————————— 公共样式,可经过 import 导入更多
- project.config.json ———————— 项目配置文件
复制代码

7.2 微信小程序生命周期

返回目录

  • onLoad():页面加载时触发。
  • onShow():页面显示/切入前台时触发。
  • onReady():页面初次渲染完成时触发。
  • onHide():页面隐藏/切入后台时触发。
  • onUnload():页面卸载时触发。

7.3 如何封装数据请求

返回目录

  1. 封装接口:

项目/utils/api.js

// 将请求进行 Promise 封装
const fetch = ({url, data}) => {

  // 打印接口请求的信息
  console.log(`【step 1】API 接口:${url}`);
  console.log("【step 2】data 传参:");
  console.log(data);

  // 返回 Promise
  return new Promise((resolve, reject) => {
    wx.request({
      url: getApp().globalData.api + url,
      data: data,
      success: res => {
        
        // 成功时的处理 
        if (res.data.code == 0) {
          console.log("【step 3】请求成功:");
          console.log(res.data);
          return resolve(res.data);
        } else {
          wx.showModal({
            title: '请求失败',
            content: res.data.message,
            showCancel: false
          });
        }

      },
      fail: err => {
        // 失败时的处理
        console.log(err);
        return reject(err);
      }
    })
  })

}

/** * code 换取 openId * @data { * jsCode - wx.login() 返回的 code * } */
export const wxLogin = data => {
  return fetch({
    url: "tbcUser/getWechatOpenId",
    data: data
  })
}
复制代码
  1. 调用接口:

项目/pages/login/login.js

import {
  wxLogin,
} from '../../utils/api.js'
复制代码
  1. 使用接口:

项目/pages/login/login.js

wxLogin({
  jsCode: this.data.code
}).then(
  res => {
    console.log("【step 4】返回成功处理:");
    console.log(res.data);
  },
  err => {
    console.log("【step 4】返回失败处理:");
    console.log(err);
  }
)
复制代码

7.4 页面数据传递

返回目录

  1. 经过 url 携带参数,在 onLoad() 中经过 options 获取 url 上的参数:

代码演示

<navigator url="../index/index?userId={{userId}}"></navigator>

<!-- 这两段是分别在 HTML 和 JS 中的代码 -->

onLoad: function(options) {
  console.log(options.userId);
}
复制代码
  1. 经过 Storage 来传递参数:
wx.setStorageSync('userId', 'jsliang');
wx.getStorageSync('userId');
复制代码
  1. WXML 传递数据到 JS

login.wxml

<text bindtap="clickText" data-labelId="{{userId}}">点击传递数据到 JS</text>
复制代码

login.js

clickText(e) {
  console.log(e.currentTarget.labelid)
}
复制代码
  1. 组件调用传参

组件接收数据:component-tag-name

Component({
  properties: {
    // 这里定义了innerText属性,属性值能够在组件使用时指定
    innerText: {
      type: String,
      value: 'default value',
    }
  }
})
复制代码

使用组件的页面定义 json

{
  "usingComponents": {
    "component-tag-name": "../component/component"
  }
}
复制代码

使用组件的页面 HTML 代码

<view>
  <!-- 如下是对一个自定义组件的引用 -->
  <component-tag-name inner-text="Some text"></component-tag-name>
</view>
复制代码
  1. 经过接口调用传递参数

7.5 加载性能优化的方法

返回目录

  1. 经过 this.$preload() 预加载用户可能点击的第二个页面。
  2. 组件化页面,出现两次以上的部分都进行封装成组件。
  3. 提取共用的 CSS 样式。
  4. 优化图片:TinyPNG

7.6 微信小程序与原生 APP、Vue、H5 差别

返回目录

  • 微信小程序优劣势:

优点

  1. 无需下载
  2. 打开速度较快
  3. 开发成本低于原生 APP

劣势

  1. 限制多。页面大小不能超过 1M,不能打开超过 5 个层级的页面。
  2. 样式单一。小程序内部组件已经成宿,样式不能够修改。
  3. 推广面窄。跑不出微信,还不能跑入朋友圈。
  • 微信小程序 VS 原生 APP

微信小程序有着低开发成本、低获客成本、无需下载的优点。

  • 微信小程序 VS H5
  1. 依赖环境不一样。一个能在多种手机浏览器运行。一个只能在微信中的非完整的浏览器。
  2. 开发成本不一样。一个可能在各类浏览器出问题。一个只能在微信中运行。
  • 微信小程序 VS Vue

微信小程序看似就是阉割版的 Vue。

7.7 微信小程序原理

返回目录

  1. 本质上就是一个单页面应用,全部的页面渲染和事件处理,都在一个页面中进行。
  2. 架构为数据驱动的模式,UI 和数据分离,全部页面的更新,都须要经过对数据的更改来实现。
  3. 微信小程序分为两个部分:webview 和 appService。其中 webview 主要用来展现 UI,appServer 用来处理业务逻辑、数据及接口调用。它们在两个进程中进行,经过系统层 JSBridge 实现通讯,实现 UI 的渲染、事件的处理。

八 浏览器

返回目录

8.1 浏览器解析 URL

返回目录

关于 浏览器解析 URLjsliang 特地将资料结合起来:

  • 防抖与节流
  • 重绘与回流
  • 浏览器解析 URL
  • DNS 域名解析
  • TCP 三次握手与四次挥手
  • 浏览器渲染页面

小伙伴们能够前往 《面试知识点 - JS 防抖与节流》 查看。

8.2 重绘与回流

返回目录

关于 重绘与回流jsliang 特地将资料结合起来:

  • 防抖与节流
  • 重绘与回流
  • 浏览器解析 URL
  • DNS 域名解析
  • TCP 三次握手与四次挥手
  • 浏览器渲染页面

小伙伴们能够前往 《面试知识点 - JS 防抖与节流》 查看。

8.3 数据存储

返回目录

  1. 存储于代码中,代码执行完毕释放内存。
  2. 存储于浏览器中,cookie 用于短时间存储用户身份,登陆状态等较小的信息;localStorage/sessionStorage 用于长期存储数据,浏览器关闭不影响它们的内存,相比于 cookie,storage 能存储较多;IndexedDB 是浏览器提供的接近于 NoSQL 的数据库,容许存储大量数据。
  3. 存储于数据库中。

8.4 内存管理与垃圾回收

返回目录

V8 将内存分为两类:新生代内存空间和老生代内存空间。

  • 新生代内存空间:主要用来存放存活时间较短的对象。
  • 老生代内存空间:主要用来存放存活时间较长的对象。

这二者经过不一样的算法,对内存进行管理操做。

8.5 内存泄漏

返回目录

  • 意外的全局变量:没法被回收。

  • 定时器:未被正确关闭,致使所引用的外部变量没法被释放。

  • 事件监听:没有正确销毁(低版本浏览器可能出现)。

  • 闭包:会致使父级中的变量没法被释放。

  • DOM 引用:DOM 被删除时,内存中的引用未被正确清空。

  • 如何查看内存变化状况?

使用 Chrome 的 Timeline(新版本 Performance)进行内存标记,可视化查看内存的变化状况,找出异常点。

九 网络协议

返回目录

9.1 网络分层

返回目录

目前网络分层可分为两种:OSI 模型和 TCP/IP 模型。

  • OSI 模型
  1. 应用层(Application)
  2. 表示层(Presentation)
  3. 会话层(Session)
  4. 传输层(Transport)
  5. 网络层(Network)
  6. 数据链路层(Data Link)
  7. 物理层(Physical)
  • TCP/IP 模型
  1. 应用层(Application)
  2. 传输层(Host-to-Host Transport)
  3. 互联网层(Internet)
  4. 网络接口层(Network Interface)

更多详情能够查看下面这篇文章,里面讲得很是详细:

9.2 HTTP/HTTPS

返回目录

  • HTTP:超文本传输协议(HTTP)是用于分布式,协做式和超媒体信息系统的应用协议。它是Web上数据交换的基础,是一种 client-server 协议,也就是说请求一般是由像浏览器这样的接受方发起的。
  • HTTPS:HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版。即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,所以加密的详细内容就须要 SSL。 它是一个 URI scheme(抽象标识符体系),句法类同 http: 体系。用于安全的HTTP数据传输。https:URL 代表它使用了 HTTP,但 HTTPS 存在不一样于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP 与 TCP 之间)。这个系统的最初研发由网景公司进行,提供了身份验证与加密通信方法,如今它被普遍用于万维网上安全敏感的通信,例如交易支付方面。

9.3 HTTP 状态码

返回目录

首先,咱们大体区分下状态码:

  1. 1**开头 - 信息提示
  2. 2**开头 - 请求成功
  3. 3**开头 - 请求被重定向
  4. 4**开头 - 请求错误
  5. 5**开头 - 服务器错误

而后,常见的状态码:

  1. 200 - 请求成功,Ajax 接受到信息了。
  2. 400 - 服务器不理解请求,工做中常见于跨域的时候后端给我报 400!
  3. 403 - 服务器拒绝请求。
  4. 404 - 请求页面错误。
  5. 500 - 服务器内部错误,没法完成请求。

最后,小伙伴们若是想要了解更多,仍是须要自行查找资料的。

9.4 TCP 三次握手与四次挥手

返回目录

关于 TCP 三次握手与四次挥手jsliang 特地将资料结合起来:

  • 防抖与节流
  • 重绘与回流
  • 浏览器解析 URL
  • DNS 域名解析
  • TCP 三次握手与四次挥手
  • 浏览器渲染页面

小伙伴们能够前往 《面试知识点 - JS 防抖与节流》 查看。

十 性能优化

返回目录

经过优化从而提升页面的加载速度。

10.1 HTML 优化

返回目录

  1. 避免 HTML 中书写 CSS 代码,由于这样难以维护。
  2. 使用 Viewport 加速页面的渲染。
  3. 使用语义化标签,减小 CSS 代码,增长可读性和 SEO。
  4. 减小标签的使用,DOM 解析是一个大量遍历的过程,减小没必要要的标签,能下降遍历的次数。
  5. 避免 src、href 等的值为空,由于即时它们为空,浏览器也会发起 HTTP 请求。
  6. 减小 DNS 查询的次数。

10.2 CSS 优化

返回目录

  1. 优化选择器路径:使用 .c {} 而不是 .a .b .c {}
  2. 选择器合并:共同的属性内容提起出来,压缩空间和资源开销。
  3. 精准样式:使用 padding-left: 10px 而不是 padding: 0 0 0 10px
  4. 雪碧图:将小的图标合并到一张图中,这样全部的图片只须要请求一次。
  5. 避免通配符:.a .b * {} 这样的选择器,根据从右到左的解析顺序在解析过程当中遇到通配符 * {} 会遍历整个 DOM,性能大大损耗。
  6. 少用 float:float 在渲染时计算量比较大,能够使用 flex 布局。
  7. 为 0 值去单位:增长兼容性。
  8. 压缩文件大小,减小资源下载负担。

10.3 JavaScript 优化

返回目录

  1. 尽量把 <script> 标签放在 body 以后,避免 JS 的执行卡住 DOM 的渲染,最大程度保证页面尽快地展现出来。
  2. 尽量合并 JS 代码:提取公共方法,进行面向对象设计等……
  3. CSS 能作的事情,尽可能不用 JS 来作,毕竟 JS 的解析执行比较粗暴,而 CSS 效率更高。
  4. 尽量逐条操做 DOM,并预约好 CSs 样式,从而减小 reflow 或者 repaint 的次数。
  5. 尽量少地建立 DOM,而是在 HTML 和 CSS 中使用 display: none 来隐藏,按需显示。
  6. 压缩文件大小,减小资源下载负担。

十一 算法

返回目录

在算法这块,jsliang 以为本身仍是比较薄弱的,若是小伙伴们跟 jsliang 同样,也想丰富下这方面知识,欢迎一块儿刷 LeetCode 共同进步:

十二 其余

返回目录

在 【其余】 这章,本来 jsliang 想谈谈面试中的一些小技巧,例如谈薪;或者讲讲 HR 面须要询问的问题,例如工做时长、加班机制、调薪机制等……

可是,最终看来,jsliang 的经历仍是有所欠缺,所经历的面试不够 “盛大”,因此说出的话可能就是 “胡言乱语”、“误导观众”,故在此就不献丑了,若是小伙伴们想知道更多,能够经过 QQ 群:798961601 找到我。

☆ 目前 jsliang 经过 3 天的请假,去了 5 场面试,收获了 3 份 offer。
☆ 若是小伙伴不知道简历该怎么写、面试老是镇静不下来、总感受面试没谱,能够先找 jsliang 聊聊,我会讲讲我的的面试经历,以及听到的其余小伙伴的经历~

十三 总结

返回目录

在观看这篇文章的过程当中,小伙伴可能会有这些疑问:

  1. 看完以为不过瘾啊!你怎么就这么 “短” 啊?

回答

系列套餐你值得拥有!

  1. 你这杂七杂八的都写了什么呀?看完我晕乎了!

回答

每一个人的学习经历是不一样的,所拥有的技术、知识点以及工做经验等都是不一样的。

因此 jsliang 的目的是经过这篇文章充实本身的同时,顺带挖掘本身的不足,例如面向对象造轮子、算法问题等让 jsliang 想进一步折腾,并应用到工做中。

所以,小伙伴应该根据本身实际去扩展补充属于本身的知识点。

毕竟了解本身的,只有本身!

  1. 好像你这里写得也不是很全啊?看完我仍是只知其一;不知其二的!

回答

每一个人的目的都是不一样的,不可能一篇文章写完全部知识点,同时有些知识点可能 jsliang 也不感兴趣、或者 jsliang 的层次不够,接触不到。

而且每一个面试官均可能有本身的一套面试题,若是 jsliang 能将全部的面试题都写出来,那还须要面试官作啥,你们都像考国家证书同样直接电脑考试吧~(我也期待!!!)

若是小伙伴对文章存有疑问,想快速获得回复。
或者小伙伴对 jsliang 我的的前端文档库感兴趣,也想将本身的前端知识整理出来。
或者小伙伴对文章后续的更新感兴趣,掌握更多的面试技巧。
欢迎加 QQ 群一块儿探讨:798961601

十四 参考文献

返回目录

本文中的许多内容,也许小伙伴看了会以为眼熟,由于它们大部分是 jsliang 参考大量文献,再通过刷选整理,最后根据本身理解后的一些阐述。

下面是我的以为很是优秀的文章。

14.1 关于面试

返回目录

  1. 《一位前端 2018 绝地求生记》
  2. 《中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)》
  3. 《InterviewMap》
  4. 《一篇文章搞定前端面试》
  5. 《微信小程序必知面试题》
  6. 《微信小程序面试题,附答案》
  7. 《小程序踩过的那些面试题坑,附答案解决方法》

14.2 关于 HTML

返回目录

  1. 《前端工程师手册》
  2. 《HTML 教程- (HTML5 标准) - 菜鸟教程》
  3. 《前端分享之cookie的使用及单点登陆》
  4. 《Cookie、session和localStorage、以及sessionStorage之间的区别》

14.3 关于 CSS

返回目录

  1. 《前端工程师手册》
  2. 《CSS 权威指南》
  3. 《CSS 揭秘》
  4. 《CSS 世界》
  5. 《我对BFC的理解》
  6. 《CSS实现垂直居中的经常使用方法》
  7. 《CSS 用 position: absolute 与 transform 来居中块级元素的问题》
  8. 《css常见布局》
  9. 《CSS3 圆角》
  10. 《CSS3 渐变(Gradients)》
  11. 《CSS3 transition 属性》
  12. 《CSS3 transform 属性》
  13. 《CSS3 animation(动画) 属性》
  14. 《CSS3 box-shadow 属性》
  15. 《我的总结(css3新特性)》

14.4 关于 JS

返回目录

  1. 【推荐】《JavaScript - MDN》
  2. 《小邵教你玩转ES6》
  3. 《小邵教你玩转JS面向对象》
  4. 《实现双向绑定Proxy比defineproperty优劣如何》
  5. 《Vue 中关于 $emit 的用法》
  6. 《JavaScript 世界万物诞生记》
  7. 《js中的new()到底作了些什么??》
  8. 《MDN Function.prototype.call()》
  9. 《JavaScript中的call、apply、bind深刻理解》
  10. 《箭头函数 - 廖雪峰》
  11. 《ECMAScript 6 入门 - 阮一峰》
  12. 《Vue原理解析之Virtual Dom》
  13. 《virtual-dom(Vue实现)简析》
  14. 《Vue.nextTick 的原理和用途》

14.5 关于其余

返回目录

  1. 《前端性能优化最佳实践》
  2. 《到底什么是前端工程化、模块化、组件化》
  3. 《【前端工程化系列】简谈前端模块化开发与开发规范》
  4. 《我的关于模块化的理解》
  5. 《组件化开发和模块化开发概念辨析》
  6. 《JavaScript模块化 --- Commonjs、AMD、CMD、es6 modules》
  7. 《浅谈什么是前端工程化》
  8. 《前端分享之cookie的使用及单点登陆》
  9. 《Cookie、session和localStorage、以及sessionStorage之间的区别》
  10. 《网络分层TCP/IP 与HTTP》

十五 网友反馈

返回目录

查看了下掘金评论区,感谢各位大大的反馈,因为本人将于 2019年4月1日 入职,故将一些我的以为不错的本身没有察觉的知识点记录下来,区分于原文,更为了猴年马月后的下一次跳槽进一步完善。

意思就是,jsliang 这货懒得改原文了,小伙伴们看着这里进行知识点补充

  • 闭包定义

函数 A 里面包含了 函数 B,而 函数 B 里面使用了 函数 A 的变量,函数 B 被 return 了出去,那么 函数 B 被称为闭包。

  • box-sizing 属性

当值为 border-box 时,宽度 width = content + padding + border,包含内边距与边框。

当值为 content-box 时,宽度 width = content,不包含内边距与边框。

  • em

em 是一个相对的大小,这里的相对于元素父元素的 font-size

  • Side Project

Side Project 对应的中文就是副业、业余项目或者小项目。

感兴趣的小伙伴能够去了解一下。

  • pushshift 系列

这里原文已备注是有误的,只是一时没空,没有修改。

  • CSS 选择器加载顺序

原文:!important -> 行内样式 -> #id -> .class -> 元素和伪元素 -> * -> 继承 -> 默认

网友:“应该是最后的优先级最高。”

这里最后的优先级最高应该是指同等级优先级覆盖。浏览器经过 CSSParser 将 CSS 解析成 CSS Rule Tree 的时候,没错的话应该是按照原文中的排序先加载,而后同等级的时候,后面的属性覆盖前面的属性。

  • ARIA

对于 HTML5 的语义化,ARIA 的意思是 Accessible Rich Internet Application,aria-* 的做用就是描述这个 Tag 在可视化的情境中的具体信息。例如:

  1. aria-label:为组件指定内置的文本标签,用来替代开发者没有使用 <label> 标签
  2. aria-labelledby:会读取与此具备相同的 id 名的值

详情可参考张鑫旭的 《WAI-ARIA无障碍网页应用属性彻底展现》

  • sessionStorage 和 localStorage

文章描述不够详细。

  • 两列布局/三列布局
  1. child-tow 中设置 width: 100% 的时候 child-one 的宽度会随机而变,设置 flex: 1 就不会。因此看我的需求进行设置。
  2. 文章中没有讲到应对兼容性怎么设置,能够考虑使用 float 进行相关的布局。
  • 浅拷贝与深拷贝

可参考文章:《深拷贝的终极探索(90%的人不知道)》

  • Promiseasync/await

文章描述不够详细。

  • 跨域

原本打算写的,后面没时间,给我删了这块,评论区有篇文献参考:

《九种跨域方式实现原理(完整版)》

以上,即为目前评论区的补充,感谢各位小伙伴的点赞支持。


jsliang 广告推送:
也许小伙伴想了解下云服务器
或者小伙伴想买一台云服务器
或者小伙伴须要续费云服务器
欢迎点击 云服务器推广 查看!

知识共享许可协议
jsliang 的文档库梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/LiangJunron…上的做品创做。
本许可协议受权以外的使用权限能够从 creativecommons.org/licenses/by… 处得到。

相关文章
相关标签/搜索