update: 目录调整

This commit is contained in:
qianguyihao
2021-04-10 11:03:41 +08:00
parent 3dfab4a196
commit 1055343951
76 changed files with 214 additions and 76 deletions

View File

@@ -0,0 +1,414 @@
## 前言
### 面试分为三部分
- 技术面试问技术问题
- 负责人面试考察综合能力比如项目把控能力项目深度项目架构业务等
- hr 面试侧重于性格沟通潜力等
每轮面试在一小时左右
### 每轮面试的知识点
一面
> 主要考察基础知识
- 页面布局
- CSS盒模型DOM事件
- HTTP 协议原型链
- 面向对象通信
- 前端安全算法
二面
- 渲染机制
- JS 运行机制
- 页面性能
- 错误监控
三面
> 不再关注技术层面
- 业务能力
- 团队协作能力
- 带人能力
终面
- 职业竞争力
- 职业规划
面试成功需要技术过关面试技巧等
### 校招和社招各自看中的层面
校招
- 知识40%
- 能力59%
- 经验1%
社招
- 知识30%比如协议业务的认知程度
- 能力50%比如架构业务的抽象能力项目的把控能力
- 经验20%项目的体现
以上仅供参考
### 面试准备
面试准备包括以下四个部分
- 职位描述JD的分析
- 业务分析
- 技术栈准备
- 自我介绍
每个公司又有一套成熟的技术栈比如在构建工具上百度用 fis3美团用 Gulp
你要面哪个公司要先看看对方要求的技术栈
上面四个部分我们接下来详细介绍
## 职位描述JD的分析
### 介绍
概念
- 职位描述注重的是工作职责
- 任职要求要求的是工作能力通常描述得很细致
PS前端的知识庞大不可能所有的内容都准备好但是要向任职要求靠拢
分析职位描述JD的目的是
- 快速识别出这个岗位是否是自己喜欢的想要的
- 目前的技能是否能胜任岗位的要求短期内的准备能否胜任
### 举例1京东 web 前端的职位描述
如下
![](http://img.smyhvae.com/20180304_2132.png)
**职位描述**
1面试时会同时考虑到 `PC 端和移动端`两个部分
2`App H5开发`指的是两层意思
- Hybrid 技术栈
- H5 开发 native 开发没有关系比如活动专题
3`调试数据接口`要学习一下怎么模拟数据
4`前端组件库的建立`要求较高但非常重要体现在
- 基本功要扎实原生 jscss的理解要到位
- 之前有没有前端组件库相关的项目经验
- 是否通读过其他的 UI 组件库
5`优化与重构`难度比第四条更大
PS前三条是基本知识第四条第五条属于进阶
**任职要求**
1`3年以上工作经验`不要太较真工作年限`精通 H5 特性`说明公司很看重移动端了解H5`最新规范`贵公司希望我对新技术是有追求的比如`ES6`
2要求我们对`面向对象`部分有足够的了解组件化的编程也离不开面向对象
3体现了几点
- `熟悉 Web 标准`熟悉最新的标准即可
- `表现与数据分离`MVC框架
- `语义化`这个词千万不要忽视不是什么都用 div
- `实际经验`利用框架开发的过程中遇到过哪些问题没有实际经验的话也要提前准备几个问题
4以下几点
- `前端架构分析与设计...`说明此岗位并不面对初级岗位因为工作一至两年的人大部分都是**做业务开发**缺少**系统的架构能力**
我们要准备一个项目的架构比如公司现有的项目重新梳理包含目录结构的设计复用性设计模块化设计自动化测试上线流是什么
- `易读、易维护的代码`面试过程中一定会让你写代码来体现要求每个函数的功能要单一能抽象尽量抽象符合这两个原则基本就满足了易读易维护
- `高质量、高效率的代码`短时间内不好准备
5`用户可用性、用户体验、用户研究`考察的不是技术而是候选人对于产品体验的理解不仅仅只是完成功能而已
6`强烈兴趣`是公司企业文化的一种要求多去GitHub上看看别人的项目里用的什么新技术多看博客短时间内无法准备
7了解`Sass``Less`这是基本技能
8**熟悉**`web构建工具`新手推荐学习 Glup而不是 grunt当然你要知道 **Glup grunt 的区别**
PS了解熟悉精通是有区别的
9暂时可以忽略如果 职位描述里没有要求`Node.js`而你只会一点点 `Node.js`那不建议你面试的时候把`Node.js`体现出来否则是给自己挖坑
### 举例2艺龙的 web 前端的职位描述
如下
![](http://img.smyhvae.com/20180304_2226.png)
此方位
**职位描述**
1`系统化设计`说的比较笼统其实指的就是模块化设计前后端分离**数据渲染**交给前端
2几点
- 前半句并没有说 H5 是放在移动端做可能同时包含 PC 和移动端
- 后半句可以看出公司对 H5 动画的要求很高动画有三种方式用DOM写SVG 的path做动画canvascanvas 又分 2D 3D我们要看岗位描述里怎么要求的既然提到CSS3那么CSS3里面的animationtansition也要了解
3微信项目要准备
- 小程序比如看贵公司有小程序吗我们自己要准备简单的开发和文档组件化的内容
- 微信支付
- 对微信开发中的哪些坑要了解
4和京东的第四条很像既要会框架也要会组件化设计但京东的侧重从零开始而艺龙侧重于有的就维护没有的就开发
**岗位要求**
1`各种`web前端技术用词不严谨
2几点
- `Web`标准JS的最新标准是ES6
- `可用性、可访问性`侧重于网站的性能 前端要做性能监控错误监控JS异常分为两种**运行异常****资源加载错误**一般人只能说出第一种异常
3`工程化`**工程化**已经是前端的必备技能`webpack`是必须的工具`grunt`已经过时了如果公司提到还是要了解`Gulp`用的很多
4写得比较虚面试时基本很难考察面试时如果写代码要注意代码风格该用 classid标签时要注意区分
5要准备一下 Node.js`至少熟悉一门`可能要求全栈开发
6`逻辑性强`能说出123
## 业务分析
> 业务分析
CSS3 动画是重点准备的内容
jQuery 要准备事件委托选择器等
ES6语法importexport等
比如<http://jr.jx.com/>这个网站:
![](http://img.smyhvae.com/20180304_2302.png)
通过简单分析源码我们初步得知网站的以下几点
- jQuery
- vue 框架
- ES6
- webpack 打包工具
## 前端技术栈准备
![](http://img.smyhvae.com/20180310_1040.png)
上图中左侧是前端技术核心右侧是前端工程化
**左侧**前端技术核心
- jQuery要注意看源码看源码时要看这几个核心架构事件委托是什么插件机制兼容性
- 三大框架都是mvvm框架准备一至两个即可或者精心准备一个面试时会问得很细比如面试官会经常问VueReact的源码建议找网上的源码分析的文章
- Node.js服务器端的运行环境如果没有相关项目经历就尽量不要提
- JavaScript 基础框架有时候都很虚熟练掌握 JavaScript 基础才是行走江湖驰骋千里的关键
**右侧**前端工程化
- npmyarn包管理工具npm的常见命令npm scripts 怎么用的
- webpack模块打包
- gulpgrunt构建工具
- SasslessCSS 预处理器
- BabelES6转ES5
## 自我介绍
面试问的问题很大层次上取决你的简历和自我介绍
### 简历
简历中最重要的四个信息
- 基本信息姓名年龄手机邮箱籍贯
- 学历从大到小写硕士 -> 本科
- 工作经历时间公司岗位职责技术栈**业绩**业绩是大多数人所忽略的
- 开源项目Github说明
自我评价可以不写
项目的业绩上要包括**技术收益****业绩收益**
### 自我陈述
1**把握面试的沟通方向**
如果陈述中谈到项目面试官可能会问
- 负责了什么项目项目是做什么的
- 和前端的结合点是你的角色是项目中承担了什么责任
- 你在项目中的成绩
如果你说自己是项目`负责人`会被问到
- 该项目怎么分配有几个人参与
- 作为负责人你的角色是什么是项目管理还是技术管理
- 遇到技术难点如何解决
### 提问题
如果在深入问题时碰到不会的不要说我不知道建议回答
- **我要回去思考一下**
- 这方面我没有经验能不能**指点一下**
- 有什么建议或者参考资料吗我想把这个东西弄懂
2阔达自信的适度发挥

View File

@@ -0,0 +1,502 @@
## 前端面试前言
### 面试基础
- 页面布局
- CSS盒模型是CSS的基石
- DOM事件
- HTTP协议
- 面向对象
- 原型链能说出原型链的始末
### 面试进阶
- 通信普通的通信跨域通信
- 安全CSRFXSS
- 算法
### 回答问题时要注意的
1题干的要求真的是字面要求的这么简单吗
2答案怎么写技巧在哪里
3如果想证明我的实力应该有几种答案
本文来讲一下页面布局
## 题目页面布局
问题假设容器的高度默认100px请写出**三栏布局**其中左栏右栏的宽度各为300px中间的宽度自适应
![](http://img.smyhvae.com/20180305_1520.png)
分析
初学者想到的答案有两种
- 方法1浮动
- 方法2绝对定位
但要求你能至少写出三四种方法才算及格剩下的方法如下
- 方法3flexbox移动开发里经常用到
- 方法4表格布局 table虽然已经淘汰了但也应该了解
- 方法5网格布局 grid
下面分别讲解
### 方法1 和方法2
**方法1浮动**
左侧设置左浮动右侧设置右浮动即可中间会自动地自适应
**方法2绝对定位**
左侧设置为绝对定位 left0px右侧设置为绝对定位 right0px中间设置为绝对定位left 和right 都为300px即可中间的宽度会自适应
使用`article`标签作为容器包裹左右三个部分
方法1 和方法2 的代码如下
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html * {
padding: 0px;
margin: 0px;
}
.layout {
margin-bottom: 150px;
}
.layout article div { /*注意这里是设置每个小块儿的高度为100px而不是设置大容器的高度。大容器的高度要符合响应式*/
height: 100px;
}
/* 方法一 start */
.layout.float .left {
float: left;
width: 300px;
background: red;
}
.layout.float .right {
float: right;
width: 300px;
background: blue;
}
.layout.float .center {
background: green;
}
/* 方法一 end */
/* 方法二 start */
.layout.absolute .left-center-right {
position: relative;
}
.layout.absolute .left {
position: absolute;
left: 0;
width: 300px;
background: red;
}
/* 【重要】中间的区域左侧定位300px右侧定位为300px即可完成。宽度会自使用 */
.layout.absolute .center {
position: absolute;
left: 300px;
right: 300px;
background: green;
}
.layout.absolute .right {
position: absolute;
right: 0;
width: 300px;
background: blue;
}
/* 方法二 end */
</style>
</head>
<body>
<!-- 方法一:浮动 start -->
<!-- 输入 section.layout.float即可生成 -->
<section class="layout float">
<!-- 用 article 标签包裹左、中、右三个部分 -->
<article class="left-right-center">
<!-- 输入 div.left+div.right+div.center即可生成 -->
<div class="left">
我是 left
</div>
<div class="right">
我是 right
</div>
<div class="center">
浮动解决方案
我是 center
</div>
</article>
</section>
<!-- 方法一:浮动 end -->
<section class="layout absolute">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="right">
我是 right
</div>
<div class="center">
<h1>绝对定位解决方案</h1>
我是 center
</div>
</article>
</section>
</body>
</html>
```
注意上方代码中 className 定义和使用非常规范
效果如下
![](http://img.smyhvae.com/20180305_1640.gif)
### 方法3flexbox布局
将左中右所在的容器设置为`display: flex`设置两侧的宽度后然后让中间的`flex = 1`即可
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html * {
padding: 0;
margin: 0;
}
.layout article div {
height: 100px;
}
.left-center-right {
display: flex;
}
.layout.flex .left {
width: 300px;
background: red;
}
.layout.flex .center {
flex: 1;
background: green;
}
.layout.flex .right {
width: 300px;
background: blue;
}
</style>
</head>
<body>
<section class="layout flex">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="center">
<h1>flex布局解决方案</h1>
我是 center
</div>
<div class="right">
我是 right
</div>
</article>
</section>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180305_1700.gif)
### 方法4表格布局 table
设置整个容器的宽度为100%设置三个部分均为表格然后左边的单元格为 300px右边的单元格为 300px即可中间的单元格会自适应
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html * {
padding: 0;
margin: 0;
}
.layout.table div {
height: 100px;
}
/* 重要设置容器为表格布局宽度为100% */
.layout.table .left-center-right {
width: 100%;
display: table;
height: 100px;
}
.layout.table .left-center-right div {
display: table-cell; /* 重要:设置三个模块为表格里的单元*/
}
.layout.table .left {
width: 300px;
background: red;
}
.layout.table .center {
background: green;
}
.layout.table .right {
width: 300px;
background: blue;
}
</style>
</head>
<body>
<section class="layout table">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="center">
<h1>表格布局解决方案</h1>
我是 center
</div>
<div class="right">
我是 right
</div>
</article>
</section>
</body>
</html>
```
![](http://img.smyhvae.com/20180305_1855.gif)
### 方法5网格布局 grid
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html * {
padding: 0;
margin: 0;
}
/* 重要设置容器为网格布局宽度为100% */
.layout.grid .left-center-right {
display: grid;
width: 100%;
grid-template-rows: 100px;
grid-template-columns: 300px auto 300px; /* 重要:设置网格为三列,并设置每列的宽度。即可。*/
}
.layout.grid .left {
background: red;
}
.layout.grid .center {
background: green;
}
.layout.grid .right {
background: blue;
}
</style>
</head>
<body>
<section class="layout grid">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="center">
<h1>网格布局解决方案</h1>
我是 center
</div>
<div class="right">
我是 right
</div>
</article>
</section>
</body>
</html>
```
效果
![](http://img.smyhvae.com/20180305_1920.gif)
### 延伸五种方法的对比
- 五种方法的优缺点
- 考虑中间模块的高度问题
- 兼容性问题实际开发中哪个最实用
方法1浮动
- 优点兼容性好
- 缺点浮动会脱离标准文档流因此要清除浮动我们解决好这个问题即可
方法:2绝对定位
- 优点快捷
- 缺点导致子元素也脱离了标准文档流可实用性差
方法3flex 布局CSS3中出现的
- 优点解决上面两个方法的不足flex布局比较完美移动端基本用 flex布局
方法4表格布局
- 优点表格布局在很多场景中很实用兼容性非常好因为IE8不支持 flex此时可以尝试表格布局
- 缺点因为三个部分都当成了**单元格**来对待此时如果中间的部分变高了其会部分也会被迫调整高度但是在很多场景下我们并不需要两侧的高度增高
什么时候用 flex 布局 or 表格布局看具体的场景二者没有绝对的优势也没有绝对的不足
方法5网格布局
- CSS3中引入的布局很好用代码量简化了很多
PS面试提到网格布局说明我们对新技术是有追求的
### 延伸如果题目中去掉高度已知
问题题目中如果去掉高度已知我们往中间的模块里塞很多内容让中间的模块撑开会发生什么变化哪个布局就不能用了
分析其实可以这样理解我们回去看上面的动画效果当中间的模块变得很挤时会发生什么效果就是我们想要的答案
答案是**flex 布局和表格布局可以通用**其他三个布局都不能用了
### 页面布局的变通
![](http://img.smyhvae.com/20180305_1931.png)
`上下高度固定,中间自适应`这个在移动端的页面中很常见
### 总结
涉及到的知识点
1语义化掌握到位每个区域用`section``article`代表容器`div`代表块儿如果通篇都用 div那就是语义化没掌握好
2页面布局理解深刻
3CSS基础知识扎实
4思维灵活且积极上进题目中可以通过`网格布局`来体现
5代码书写规范注意命名上面的代码中没有一行代码是多的

View File

@@ -0,0 +1,438 @@
> 本文最初发表于[博客园](http://www.cnblogs.com/smyhvae/p/8512617.html),并在[GitHub](https://github.com/smyhvae/Web)上持续更新**前端的系列文章**。欢迎在GitHub上关注我一起入门和进阶前端。
> 以下是正文
## 题目谈一谈你对CSS盒模型的认识
专业的面试一定会问 CSS 盒模型对于这个题目我们要回答一下几个方面
1基本概念contentpaddingmargin
2标准盒模型IE盒模型的区别不要漏说了IE盒模型通过这个问题可以筛选一部分人
3CSS如何设置这两种模型如何设置某个盒子为其中一个模型如果回答了上面的第二条还会继续追问这一条
4JS如何设置获取盒模型对应的宽和高这一步已经有很多人答不上来了
5实例题根据盒模型解释**边距重叠**
前四个方面是逐渐递增第五个方面却鲜有人知
6BFC边距重叠解决方案或IFC
如果能回答第五条就会引出第六条BFC是面试频率较高的
**总结**以上几点从上到下知识点逐渐递增知识面从理论CSSJS又回到CSS理论
接下来我们把上面的六条依次讲解
## 标准盒模型和IE盒子模型
标准盒子模型
![](http://img.smyhvae.com/2015-10-03-css-27.jpg)
IE盒子模型
![](http://img.smyhvae.com/2015-10-03-css-30.jpg)
上图显示
CSS 盒子模型 (Box Model) 规定了元素处理元素的几种方式
- width和height**内容**的宽度高度不是盒子的宽度高度
- padding内边距
- border边框
- margin外边距
CSS盒模型和IE盒模型的区别
- <font color="#0000FF">**标准盒子模型**</font><font color="#0000FF">**width height **</font>
- <font color="#0000FF">**IE盒子模型**</font><font color="#0000FF">**width height +border+padding**</font>
## CSS如何设置这两种模型
代码如下
```javascript
/* 设置当前盒子为 标准盒模型(默认) */
box-sizing: content-box;
/* 设置当前盒子为 IE盒模型 */
box-sizing: border-box;
```
备注盒子默认为标准盒模型
## JS如何设置获取盒模型对应的宽和高
### 方式一通过DOM节点的 style 样式获取
```javascript
element.style.width/height;
```
缺点通过这种方式只能获取**行内样式**不能获取`内嵌`的样式和`外链`的样式
这种方式有局限性但应该了解
### 方式二通用型
```javascript
window.getComputedStyle(element).width/height;
```
方式二能兼容 Chrome火狐是通用型方式
### 方式三IE独有的
```javascript
element.currentStyle.width/height;
```
和方式二相同但这种方式只有IE独有获取到的即时运行完之后的宽高三种css样式都可以获取
### 方式四
```javascript
element.getBoundingClientRect().width/height;
```
api 的作用是获取一个元素的绝对位置绝对位置是视窗 viewport 左上角的绝对位置
api 可以拿到四个属性lefttopwidthheight
**总结**
上面的四种方式要求能说出来区别以及哪个的通用型更强
## margin塌陷/margin重叠
**标准文档流中竖直方向的margin不叠加只取较大的值作为margin**(水平方向的margin是可以叠加的即水平方向没有塌陷现象)
PS如果不在标准流比如盒子都浮动了那么两个盒子之间是没有margin重叠的现象的
我们来看几个例子
### 兄弟元素之间
如下图所示
![](http://img.smyhvae.com/20170805_0904_2.png)
### 子元素和父元素之间
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.father {
background: green;
}
/* 给儿子设置margin-top为10像素 */
.son {
height: 100px;
margin-top: 10px;
background: red;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
```
上面的代码中儿子的height是 100pxmagin-top 是10px注意此时父亲的 height 是100而不是110因为儿子和父亲在竖直方向上共一个margin
儿子这个盒子
![](http://img.smyhvae.com/20180305_2216.png)
父亲这个盒子
![](http://img.smyhvae.com/20180305_2217.png)
上方代码中如果我们给父亲设置一个属性`overflow: hidden`就可以避免这个问题此时父亲的高度是110px这个用到的就是BFC下一段讲解
### 善于使用父亲的padding而不是儿子的margin
> 其实这一小段讲的内容与上一小段相同都是讲父子之间的margin重叠
我们来看一个奇怪的现象现在有下面这样一个结构div中放一个p
```
<div>
<p></p>
</div>
```
上面的结构中我们尝试通过给儿子`p`一个`margin-top:50px;`的属性让其与父亲保持50px的上边距结果却看到了下面的奇怪的现象
![](http://img.smyhvae.com/20170806_1537.png)
此时我们给父亲div加一个border属性就正常了
![](http://img.smyhvae.com/20170806_1544.png)
如果父亲没有border那么儿子的margin实际上踹的是踹的是这所以父亲整体也掉下来了
**margin这个属性本质上描述的是兄弟和兄弟之间的距离 最好不要用这个marign表达父子之间的距离**
所以如果要表达父子之间的距离我们一定要善于使用父亲的padding而不是儿子的margin
## BFC边距重叠解决方案
### BFC的概念
BFCBlock Formatting Context块级格式化上下文你可以把它理解成一个独立的区域
另外还有个概念叫IFC不过BFC问得更多
### BFC 的原理/BFC的布局规则非常重要
BFC 的原理其实也就是 BFC 的渲染规则能说出以下四点就够了包括
- 1BFC **内部的**子元素在垂直方向**边距会发生重叠**
- 2BFC在页面中是独立的容器外面的元素不会影响里面的元素反之亦然稍后看`举例1`
- 3**BFC区域不与旁边的`float box`区域重叠**可以用来清除浮动带来的影响稍后看`举例2`
- 4计算BFC的高度时浮动的子元素也参与计算稍后看`举例3`
### 如何生成BFC
有以下几种方法
- 方法1overflow: 不为visible可以让属性是 hiddenauto最常用
- 方法2浮动中float的属性值不为none意思是只要设置了浮动当前元素就创建了BFC
- 方法3定位中只要posiiton的值不是 static或者是relative即可可以是`absolute``fixed`也就生成了一个BFC
- 方法4display为inline-block, table-cell, table-caption, flex, inline-flex
参考链接
- [BFC原理详解](https://segmentfault.com/a/1190000006740129)
- [BFC详解](https://www.jianshu.com/p/bf927bc1bed4)
- [前端精选文摘BFC 神奇背后的原理](https://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html)
下面来看几个例子看看如何生成BFC
### BFC 的应用
**举例1**解决 margin 重叠
当父元素和子元素发生 margin 重叠时解决办法**给子元素或父元素创建BFC**
比如说针对下面这样一个 div 结构
```html
<div class="father">
<p class="son">
</p>
</div>
```
上面的div结构中如果父元素和子元素发生margin重叠我们可以给子元素创建一个 BFC就解决了
```html
<div class="father">
<p class="son" style="overflow: hidden">
</p>
</div>
```
因为**第二条BFC区域是一个独立的区域不会影响外面的元素**
**举例2**BFC区域不与float区域重叠
针对下面这样一个div结构
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.father-layout {
background: pink;
}
.father-layout .left {
float: left;
width: 100px;
height: 100px;
background: green;
}
.father-layout .right {
height: 150px; /*右侧标准流里的元素,比左侧浮动的元素要高*/
background: red;
}
</style>
</head>
<body>
<section class="father-layout">
<div class="left">
左侧,生命壹号
</div>
<div class="right">
右侧smyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvae
</div>
</section>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180306_0825.png)
上图中由于右侧标准流里的元素比左侧浮动的元素要高导致右侧有一部分会跑到左边的下面去
**如果要解决这个问题可以将右侧的元素创建BFC**因为**第三条BFC区域不与`float box`区域重叠**解决办法如下将right区域添加overflow属性
```html
<div class="right" style="overflow: hidden">
右侧smyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvaesmyhvae
</div>
```
![](http://img.smyhvae.com/20180306_0827.png)
上图表明解决之后`father-layout`的背景色显现出来了说明问题解决了
**举例3**清除浮动
现在有下面这样的结构
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.father {
background: pink;
}
.son {
float: left;
background: green;
}
</style>
</head>
<body>
<section class="father">
<div class="son">
生命壹号
</div>
</section>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180306_0840.png)
上面的代码中儿子浮动了但由于父亲没有设置高度导致看不到父亲的背景色此时父亲的高度为0正所谓**有高度的盒子才能关住浮动**
如果想要清除浮动带来的影响方法一是给父亲设置高度然后采用隔墙法方法二是 BFC给父亲增加 `overflow=hidden`属性即可 增加之后效果如下
![](http://img.smyhvae.com/20180306_0845.png)
为什么父元素成为BFC之后就有了高度呢这就回到了**第四条计算BFC的高度时浮动元素也参与计算**意思是**在计算BFC的高度时子元素的float box也会参与计算**
## 我的公众号
想学习<font color=#0000ff>**代码之外的技能**</font>****id`qianguyihao`
扫一扫你将发现另一个全新的世界而这将是一场美丽的意外
![](http://img.smyhvae.com/2016040102.jpg)

View File

@@ -0,0 +1,311 @@
## 前言
要学习事件的基础内容请看先本人之前的基础文章
- 04-JavaScript基础/27-事件对象Event
- 04-JavaScript基础/28-事件捕获和事件冒泡
- 04-JavaScript基础/29-事件委托
知识难度不大只是大家需要系统地学习
**知识点主要包括以下几个方面**
- 基本概念DOM事件的级别
面试不会直接问你DOM有几个级别但会在题目中体现请用DOM2 ....
- DOM事件模型DOM事件流
面试官如果问你**DOM事件模型**你不一定知道怎么回事其实说的就是**捕获和冒泡**
**DOM事件流**指的是事件传递的**三个阶段**
- 描述DOM事件捕获的具体流程
讲的是事件的传递顺序参数为false默认参数为true各自代表事件在什么阶段触发
能回答出来的人寥寥无几也许有些人可以说出一大半但是一字不落的人极少
- Event对象的常见应用Event的常用api方法
DOM事件的知识点一方面包括事件的流程另一方面就是怎么去注册事件也就是监听用户的交互行为第三点在响应时Event对象是非常重要的
- 自定义事件非常重要
一般人可以讲出事件和注册事件但是如果让你讲**自定义事件**能知道的人就更少了
- 事件委托
业务中经常用到
下面分别讲解
## DOM事件的级别
DOM事件的级别准确来说**DOM标准**定义的级别包括
**DOM0的写法**
```javascript
element.onclick = function () {
}
```
上面的代码是在 js 中的写法如果要在html中写写法是在onclick属性中 js 语句
**DOM2的写法**
```javascript
element.addEventListener('click', function () {
}, false);
```
重要上面的第三参数中**true**表示事件在**捕获阶段**触发**false**表示事件在**冒泡阶段**触发默认如果不写则默认为false
**DOM3的写法**
```javascript
element.addEventListener('keyup', function () {
}, false);
```
DOM3中增加了很多事件类型比如鼠标事件键盘事件等
PS为何事件没有DOM1的写法呢因为DOM1标准制定的时候没有涉及与事件相关的内容
**总结**关于DOM事件的级别能回答出以上内容即可不会出题目让你做
## DOM事件模型DOM事件流
### DOM事件模型
DOM事件模型讲的就是**捕获和冒泡**一般人都能回答出来
- 捕获从上往下
- 冒泡从下目标元素往上
### DOM事件流
DOM事件流讲的就是浏览器在于当前页面做交互时这个事件是怎么传递到页面上的
类似于Android里面的事件传递
完整的事件流分三个阶段
- 1捕获 window 对象传到 目标元素
- 2目标阶段事件通过捕获到达目标元素这个阶段就是目标阶段
- 3冒泡**目标元素**传到 Window 对象
![](http://img.smyhvae.com/20180306_1058.png)
![](http://img.smyhvae.com/20180204_1218.jpg)
## 描述DOM事件捕获的具体流程
> 很少有人能说完整
### 捕获的流程
![](http://img.smyhvae.com/20180306_1103.png)
**说明**捕获阶段事件依次传递的顺序是window --> document --> html--> body --> 父元素子元素目标元素
PS1第一个接收到事件的对象是 **window**有人会说body有人会说html这都是错误的
PS2JS中涉及到DOM对象时有两个对象最常用windowdoucument它们俩也是最先获取到事件的
代码如下
```javascript
window.addEventListener("click", function () {
alert("捕获 window");
}, true);
document.addEventListener("click", function () {
alert("捕获 document");
}, true);
document.documentElement.addEventListener("click", function () {
alert("捕获 html");
}, true);
document.body.addEventListener("click", function () {
alert("捕获 body");
}, true);
fatherBox.addEventListener("click", function () {
alert("捕获 father");
}, true);
childBox.addEventListener("click", function () {
alert("捕获 child");
}, true);
```
**补充一个知识点**
js中
- 如果想获取 `body` 节点方法是`document.body`
- 但是如果想获取 `html`节点方法是`document.documentElement`
### 冒泡的流程
与捕获的流程相反
## Event对象的常见 api 方法
用户做的是什么操作比如是敲键盘了还是点击鼠标了这些事件基本都是通过Event对象拿到的这些都比较简单我们就不讲了我们来看看下面这几个方法
### 方法一
```javascript
event.preventDefault();
```
解释阻止默认事件
比如已知`<a>`标签绑定了click事件此时如果给`<a>`设置了这个方法就阻止了链接的默认跳转
### 方法二阻止冒泡
这个在业务中很常见
有的时候业务中不需要事件进行冒泡比如说业务这样要求单击子元素做事件A单击父元素做事件B如果不阻止冒泡的话出现的问题是单击子元素时子元素和父元素都会做事件A这个时候就要用到阻止冒泡了
w3c的方法火狐谷歌IE11
```javascript
event.stopPropagation();
```
IE10以下则是
```javascript
event.cancelBubble = true;
```
兼容代码如下
```javascript
box3.onclick = function (event) {
alert("child");
//阻止冒泡
event = event || window.event;
if (event && event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
```
上方代码中我们对box3进行了阻止冒泡产生的效果是事件不会继续传递到 fathergrandfatherbody了
### 方法三设置事件优先级
```javascript
event.stopImmediatePropagation();
```
这个方法比较长一般人没听说过解释如下
比如说我用addEventListener给某按钮同时注册了事件A事件B此时如果我单击按钮就会依次执行事件A和事件B现在要求单击按钮时只执行事件A不执行事件B该怎么做呢这是时候就可以用到`stopImmediatePropagation`方法了做法是在事件A的响应函数中加入这句话
大家要记住 event 有这个方法
### 属性4属性5事件委托中用到
```javascript
event.currentTarget //当前所绑定的事件对象。在事件委托中,指的是【父元素】。
event.target //当前被点击的元素。在事件委托中,指的是【子元素】。
```
上面这两个属性在事件委托中经常用到
**总结**上面这几项非常重要但是容易弄混淆
## 自定义事件
自定义事件的代码如下
```javascript
var myEvent = new Event('clickTest');
element.addEventListener('clickTest', function () {
console.log('smyhvae');
});
//元素注册事件
element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent不是写 事件名 clickTest
```
上面这个事件是定义完了之后就直接自动触发了在正常的业务中这个事件一般是和别的事件结合用的比如延时器设置按钮的动作
```javascript
var myEvent = new Event('clickTest');
element.addEventListener('clickTest', function () {
console.log('smyhvae');
});
setTimeout(function () {
element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent不是写 事件名 clickTest
}, 1000);
```
## 事件委托
参考本人这篇文章的最后一段
- 04-JavaScript基础/29-事件委托

View File

@@ -0,0 +1,216 @@
一面中如果有笔试考HTTP协议的可能性较大
## 前言
一面要讲的内容
- HTTP协议的主要特点
- HTTP报文的组成部分
- HTTP方法
- get post的区别
- HTTP状态码
- 什么是持久连接
- 什么是管线化
二面要讲的内容
- 缓存
- CSRF攻击
## HTTP协议的主要特点
- 简单快速
- 灵活
- **无连接**
- **无状态**
通常我们要答出以上四个内容如果实在记不住一定要记得后面的两个**无连接无状态**
我们分别来解释一下
### 简单快速
**简单**每个资源比如图片页面都通过 url 来定位这都是固定的在http协议中处理起来也比较简单想访问什么资源直接输入url即可
### 灵活
http协议的头部有一个`数据类型`通过http协议就可以完成不同数据类型的传输
### 无连接
连接一次就会断开不会继续保持连接
### 无状态
客户端和服务器端是两种身份第一次请求结束后就断开了第二次请求时**服务器端并没有记住之前的状态**也就是说服务器端无法区分客户端是否为同一个人同一个身份
有的时候我们访问网站时网站能记住我们的账号这个是通过其他的手段比如 session做到的并不是http协议能做到的
## HTTP报文的组成部分
![](http://img.smyhvae.com/20180306_1400.png)
在回答此问题时我们要按照顺序回答
- 先回答的是http报文包括**请求报文****响应报文**
- 再回答的是每个报文包含什么部分
- 最后回答每个部分的内容是什么
### 请求报文包括
![](http://img.smyhvae.com/20180228_1505.jpg)
- 请求行包括请求方法请求的urlhttp协议及版本
- 请求头一大堆的键值对
- **空行**指的是当服务器在解析请求头的时候如果遇到了空行则表明后面的内容是请求体
- 请求体数据部分
### 响应报文包括
![](http://img.smyhvae.com/20180228_1510.jpg)
- 状态行http协议及版本状态码及状态描述
- 响应头
- 空行
- 响应体
## HTTP方法
包括
- GET获取资源
- POST传输资源
- put更新资源
- DELETE删除资源
- HEAD获得报文首部
HTTP方法有很多但是上面这五个方法要求在面试时全部说出来不要漏掉
get post 比较常见
put delete 在实际应用中用的很少况且业务中一般不删除服务器端的资源
head 可能偶尔用的到
## get post的区别
![](http://img.smyhvae.com/20180306_1415.png)
区别有很多如果记不住面试时至少要任意答出其中的三四条
有一点要强调**get是相对不隐私的而post是相对隐私的**
我们大概要记住以下几点
1浏览器在回退时get**不会重新请求**但是post会重新请求重要
2get请求会被浏览器**主动缓存**而post不会重要
3get请求的参数会报**保留**在浏览器的**历史记录**而post不会做业务时要注意为了防止CSRF攻击很多公司把get统一改成了post
4get请求在url中传递的参数有大小限制基本是2kb不同的浏览器略有不同而post没有注意
5get的参数是直接暴露在url上的相对不安全而post是放在请求体中的
## http状态码
http状态码分类
![](http://img.smyhvae.com/20180306_1430.png)
常见的http状态码
![](http://img.smyhvae.com/20180306_1431.png)
部分解释
- 206的应用`range`指的是请求的范围客户端只请求某个大文件里的一部分内容比如说如果播放视频地址或音频地址的前面一部分可以用到206
- 301重定向永久
- 302重定向临时
- 304我这个服务器告诉客户端你已经有缓存了不需要从我这里取了
![](http://img.smyhvae.com/20180306_1440.png)
400和401用的不多403指的是请求被拒绝404指的是资源不存在
## 持久链接/http长连接
> 如果你能答出持久链接这是面试官很想知道的一个点
- **轮询**http1.0客户端每隔很短的时间都会对服务器发出请求查看是否有新的消息只要轮询速度足够快例如1秒就能给人造成交互是实时进行的印象这种做法是无奈之举实际上对服务器客户端双方都造成了大量的性能浪费
- **长连接**HTTP1.1通过使用Connection:keep-alive进行长连接客户端只请求一次但是服务器会将继续保持连接当再次请求时避免了重新建立连接
注意HTTP 1.1默认进行持久连接在一次 TCP 连接中可以完成多个 HTTP 请求但是对**每个请求仍然要单独发 header**Keep-Alive不会永久保持连接它有一个保持时间可以在不同的服务器软件如Apache中设定这个时间
## 长连接中的管线化
> 如果能答出**管线化**则属于加分项
### 管线化的原理
长连接时**默认**的请求这样的
```
请求1 --> 响应1 -->请求2 --> 响应2 --> 请求3 --> 响应3
```
长连接中的管线化请求是这样的
```
请求1 --> 请求2 --> 请求3 --> 响应1 --> 响应2 --> 响应3
```
管线化就是我把现在的请求打包一次性发过去你也给我一次响应回来
### 管线化的注意事项
面试时不会深究管线化如果真要问你就回答我没怎么研究过准备回去看看~

View File

@@ -0,0 +1,190 @@
## 前言
### 面向对象的三大特性
- 封装
- 继承
- 多态
### 原型链的知识
原型链是面向对象的基础是非常重要的部分有以下几种知识
- 创建对象有几种方法
- 原型构造函数实例原型链
- `instanceof`的原理
- new 运算符
## 创建对象有几种方法
### 方式一字面量
```javascript
var obj11 = {name: 'qianguyihao'};
var obj12 = new Object(name: 'qianguyihao'); //内置对象(内置的构造函数)
```
上面的两种写法效果是一样的因为第一种写法`obj11`会指向`Object`
- 第一种写法是字面量的方式
- 第二种写法是内置的构造函数
### 方式二通过构造函数
```javascript
var M = function (name) {
this.name = name;
}
var obj3 = new M('smyhvae');
```
### 方法三Object.create
```javascript
var p = {name:'smyhvae'};
var obj3 = Object.create(p); //此方法创建的对象,是用原型链连接的
```
第三种方法很少有人能说出来这种方式里obj3是实例p是obj3的原型name是p原型里的属性构造函数是`Objecet`
![](http://img.smyhvae.com/20180306_1633.png)
## 原型构造函数实例以及原型链
![](http://img.smyhvae.com/20180306_1540.png)
PS任何一个函数如果在前面加了new那就是构造函数
### 原型构造函数实例三者之间的关系
![](http://img.smyhvae.com/20180306_2107.png)
- 1构造函数通过 new 生成实例
- 2构造函数也是函数构造函数的`prototype`指向原型所有的函数有`prototype`属性但实例没有 `prototype`属性
- 3原型对象中有 constructor指向该原型的构造函数
上面的三行代码演示
```
var Foo = function (name) {
this.name = name;
}
var foo = new Foo('smyhvae');
```
上面的代码中`Foo.prototype.constructor === Foo`的结果是`true`
![](http://img.smyhvae.com/20180306_2120.png)
- 4实例的`__proto__`指向原型也就是说`foo.__proto__ === Foo.prototype`
声明所有的**引用类型**数组对象函数都有`__proto__`这个属性
`Foo.__proto__ === Function.prototype`的结果为true说明Foo这个普通的函数是Function构造函数的一个实例
### 原型链
**原型链的基本原理**任何一个**实例**通过原型链找到它上面的**原型**该原型对象中的方法和属性可以被所有的原型实例共享
Object是原型链的顶端
原型可以起到继承的作用原型里的方法都可以被不同的实例共享
```
//给Foo的原型添加 say 函数
Foo.prototype.say = function () {
console.log('');
}
```
**原型链的关键**在访问一个实例的时候如果实例本身没找到此方法或属性就往原型上找如果还是找不到继续往上一级的原型上找
### `instanceof`的原理
![](http://img.smyhvae.com/20180306_2209.png)
`instanceof`**作用**用于判断**实例**属于哪个**构造函数**
`instanceof`**原理**判断实例对象的`__proto__`属性和构造函数的`prototype`属性是否为同一个引用是否指向同一个地址
**注意1**虽然说实例是由构造函数 new 出来的但是实例的`__proto__`属性引用的是构造函数的`prototype`也就是说实例的`__proto__`属性与构造函数本身无关
**注意2**在原型链上原型的上面可能还会有原型以此类推往上走继续找`__proto__`属性这条链上如果能找到 instanceof 的返回结果也是 true
比如说
- `foo instance of Foo`的结果为true因为`foo.__proto__ === Foo.prototype`为true
- **`foo instance of Objecet`的结果也为true**因为`Foo.prototype.__proto__ === Object.prototype`为true
但我们不能轻易的说`foo 一定是 由Object创建的实例`这句话是错误的我们来看下一个问题就明白了
### 分析一个问题
**问题**已知A继承了BB继承了C怎么判断 a 是由A**直接生成**的实例还是B直接生成的实例呢还是C直接生成的实例呢
分析这就要用到原型的`constructor`属性了
- `foo.__proto__.constructor === Foo`的结果为true但是 `foo.__proto__.constructor === Object`的结果为false
所以 consturctor判断就比用 instanceof判断更为严谨
## new 运算符
当new Foo()时发生了什么
1创建一个**新的空对象实例**
2将此空对象的隐式原型指向其构造函数的显示原型
3执行构造函数传入相应的参数如果没有参数就不用传同时 this 指向这个新实例
4如果返回值是一个新对象那么直接返回该对象如果无返回值或者返回一个非对象值那么就将步骤1创建的对象返回
参考JS高程6.2.2
## 类继承和原型继承的区别
```javascript
```

View File

@@ -0,0 +1,177 @@
## 前言
类与实例
- 类的声明
- 生成实例
类与继承
- 如何实现继承继承的本质就是原型链
- 继承的几种方式
## 类的定义实例化
### 类的定义/类的声明
**方式一**用构造函数模拟类传统写法
```javascript
function Animal1() {
this.name = 'smyhvae'; //通过this表明这是一个构造函数
}
```
**方式二** class 声明ES6的写法
```javascript
class Animal2 {
constructor() { //可以在构造函数里写属性
this.name = name;
}
}
```
控制台的效果
![](http://img.smyhvae.com/20180307_0957.png)
### 实例化
类的实例化很简单直接 new 出来即可
```javascript
console.log(new Animal1(),new Animal2()); //实例化。如果括号里没有参数,则括号可以省略
```
![](http://img.smyhvae.com/20180307_1000.png)
## 继承的几种方式
继承的本质就是原型链
**继承的方式有几种每种形式的优缺点是**这些问题必问的其实就是考察你对原型链的掌握程度
### 方式一借助构造函数
```javascript
function Parent1() {
this.name = 'parent1 的属性';
}
function Child1() {
Parent1.call(this); //【重要】此处用 call 或 apply 都行:改变 this 的指向
this.type = 'child1 的属性';
}
console.log(new Child1);
```
重要上方代码中最重要的那行代码在子类的构造函数里写了`Parent1.call(this);`意思是**让Parent的构造函数在child的构造函数中执行**发生的变化是**改变this的指向**parent的实例 --> 改为指向child的实例导致 parent的实例的属性挂在到了child的实例上这就实现了继承
打印结果
![](http://img.smyhvae.com/20180307_1015.png)
上方结果表明child先有了 parent 实例的属性继承得以实现再有了child 实例的属性
**分析**
这种方式虽然改变了 this 的指向但是**Child1 无法继承 Parent1 的原型**也就是说如果我给 Parent1 的原型增加一个方法
```javascript
Parent1.prototype.say = function () {
};
```
上面这个方法是无法被 Child1 继承的如下
![](http://img.smyhvae.com/20180307_1030.png)
### 方法二通过原型链实现继承
```javascript
/*
通过原型链实现继承
*/
function Parent() {
this.name = 'Parent 的属性';
}
function Child() {
this.type = 'Child 的属性';
}
Child.prototype = new Parent(); //【重要】
console.log(new Child());
```
打印结果
![](http://img.smyhvae.com/20180307_1109.png)
重要上方代码中最重要的那行每个函数都有`prototype`属性于是构造函数也有这个属性这个属性是一个对象现在**我们把`Parent`的实例赋值给了`Child``prototype`**从而实现**继承**此时`Child`构造函数`Parent`的实例`Child`的实例构成一个三角关系于是
- `new Child.__proto__ === new Parent()`的结果为true
**分析**
这种继承方式**Child 可以继承 Parent 的原型**但有个缺点
缺点是**如果修改 child1实例的name属性child2实例中的name属性也会跟着改变**
如下
![](http://img.smyhvae.com/20180307_1123.png)
上面的代码中 child1修改了arr属性却发现child2的arr属性也跟着改变了这显然不太好在业务中两个子模块应该隔离才对如果改了一个对象另一个对象却发生了改变就不太好
造成这种缺点的原因是child1和child2共用原型`chi1d1.__proto__ === child2__proto__`是严格相同 arr方法是在 Parent 的实例上 Child实例的原型
## 方式三组合的方式构造函数 + 原型链
就是把上面的两种方式组合起来
```javascript
/*
组合方式实现继承:构造函数、原型链
*/
function Parent3() {
this.name = 'Parent 的属性';
this.arr = [1, 2, 3];
}
function Child3() {
Parent3.call(this); //【重要1】执行 parent方法
this.type = 'Child 的属性';
}
Child3.prototype = new Parent3(); //【重要2】第二次执行parent方法
var child = new Child3();
```
这种方式能解决之前两种方式的问题既可以继承父类原型的内容也不会造成原型里属性的修改
这种方式的缺点是让父亲Parent的构造方法执行了两次
```javascript
```
ES6中的继承方式一带而过即可重点是要掌握ES5中的继承

View File

@@ -0,0 +1,508 @@
> 本文最初发表于[博客园](https://www.cnblogs.com/smyhvae/p/8523576.html),并在[GitHub](https://github.com/qianguyihao/Web)上持续更新**前端的系列文章**。欢迎在GitHub上关注我一起入门和进阶前端。
> 以下是正文
## 前言
从本章起对代码的要求没之前那么高了但是要求你对知识面的掌握要足够宽
前端通信类的问题主要包括以下内容
- 1什么是**同源策略**及限制
同源策略是一个概念就一句话有什么限制就三句话能说出来即可
- 2**前后端如何通信**
如果你不准备估计也就只能说出ajax这个可以考察出知识面
- 3如何创建**Ajax**
Ajax在前后端通信中经常用到做业务时可以借助第三方的库比如vue框架里的库jQuery也有封装好的方法但如果让你用原生的js去实现该怎么做
这就是考察你的动手能力以及框架原理的掌握如果能写出来可以体现出你的基本功是加分项
- 4**跨域通信**的几种方式
这部分非常重要无非就是问你什么是跨域跨域有什么限制**跨域有几种方式**
下面分别讲解
## 同源策略的概念和具体限制
**同源策略**限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互这是一个用于隔离潜在恶意文件的关键的安全机制来自MDN官方的解释
具体解释
1``包括三个部分协议域名端口http协议的默认端口是80如果有任何一个部分不同``不同那就是跨域了
2`限制`这个源的文档没有权利去操作另一个源的文档这个限制体现在要记住
- CookieLocalStorage和IndexDB无法获取
- 无法获取和操作DOM
- 不能发送Ajax请求我们要注意Ajax只适合**同源**的通信
## 前后端如何通信
主要有以下几种方式
- Ajax不支持跨域
- WebSocket不受同源策略的限制支持跨域
- CORS不受同源策略的限制支持跨域一种新的通信协议标准可以理解成是**同时支持同源和跨域的Ajax**
## 如何创建Ajax
> 关于Ajax请求可以看本人的基础文章[Ajax入门和发送http请求](https://github.com/smyhvae/Web/blob/master/08-Ajax/02-Ajax%E5%85%A5%E9%97%A8%E5%92%8C%E5%8F%91%E9%80%81http%E8%AF%B7%E6%B1%82.md)
在回答 Ajax 的问题时要回答以下几个方面
- 1XMLHttpRequest 的工作原理
- 2兼容性处理
XMLHttpRequest只有在高级浏览器中才支持在回答问题时这个兼容性问题不要忽略
- 3事件的触发条件
- 4事件的触发顺序
XMLHttpRequest有很多触发事件每个事件是怎么触发的
### 发送 Ajax 请求的五个步骤XMLHttpRequest的工作原理
1创建XMLHttpRequest 对象
2使用open方法设置请求的参数open(method, url, 是否异步)
3发送请求
4注册事件 注册onreadystatechange事件状态改变时就会调用
如果要在数据完整请求回来的时候才调用我们需要手动写一些判断的逻辑
5获取返回的数据更新UI
### 发送 get 请求和 post 请求
get请求举例
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>Ajax 发送 get 请求</h1>
<input type="button" value="发送get_ajax请求" id='btnAjax'>
<script type="text/javascript">
// 绑定点击事件
document.querySelector('#btnAjax').onclick = function () {
// 发送ajax 请求 需要 五步
// 1创建异步对象
var ajaxObj = new XMLHttpRequest();
// 2设置请求的参数。包括请求的方法、请求的url。
ajaxObj.open('get', '02-ajax.php');
// 3发送请求
ajaxObj.send();
//4注册事件。 onreadystatechange事件状态改变时就会调用。
//如果要在数据完整请求回来的时候才调用,我们需要手动写一些判断的逻辑。
ajaxObj.onreadystatechange = function () {
// 为了保证 数据 完整返回,我们一般会判断 两个值
if (ajaxObj.readyState == 4 && ajaxObj.status == 200) {
// 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
// 5.在注册的事件中 获取 返回的 内容 并修改页面的显示
console.log('数据返回成功');
// 数据是保存在 异步对象的 属性中
console.log(ajaxObj.responseText);
// 修改页面的显示
document.querySelector('h1').innerHTML = ajaxObj.responseText;
}
}
}
</script>
</body>
</html>
```
post 请求举例
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>Ajax 发送 get 请求</h1>
<input type="button" value="发送put_ajax请求" id='btnAjax'>
<script type="text/javascript">
// 异步对象
var xhr = new XMLHttpRequest();
// 设置属性
xhr.open('post', '02.post.php');
// 如果想要使用post提交数据,必须添加此行
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 将数据通过send方法传递
xhr.send('name=fox&age=18');
// 发送并接受返回值
xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
</script>
</body>
</html>
```
### onreadystatechange 事件
注册 onreadystatechange 事件后每当 readyState 属性改变时就会调用 onreadystatechange 函数
readyState存有 XMLHttpRequest 的状态 0 4 发生变化
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成且响应已就绪
### 事件的触发条件
![](http://img.smyhvae.com/20180307_1443.png)
### 事件的触发顺序
![](http://img.smyhvae.com/20180307_1445.png)
上图的参考链接
- [你真的会使用XMLHttpRequest吗](https://segmentfault.com/a/1190000004322487)
### 实际开发中用的 原生Ajax请求
```javascript
var util = {};
//获取 ajax 请求之后的json
util.json = function (options) {
var opt = {
url: '',
type: 'get',
data: {},
success: function () {
},
error: function () {
},
};
util.extend(opt, options);
if (opt.url) {
//IE兼容性处理浏览器特征检查。检查该浏览器是否存在XMLHttpRequest这个api没有的话就用IE的api
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHTTP');
var data = opt.data,
url = opt.url,
type = opt.type.toUpperCase();
dataArr = [];
}
for (var key in data) {
dataArr.push(key + '=' + data[key]);
}
if (type === 'GET') {
url = url + '?' + dataArr.join('&');
xhr.open(type, url.replace(/\?$/g, ''), true);
xhr.send();
}
if (type === 'POST') {
xhr.open(type, url, true);
// 如果想要使用post提交数据,必须添加此行
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(dataArr.join('&'));
}
xhr.onload = function () {
if (xhr.status === 200 || xhr.status === 304) { //304表示用缓存即可。206表示获取媒体资源的前面一部分
var res;
if (opt.success && opt.success instanceof Function) {
res = xhr.responseText;
if (typeof res === 'string') {
res = JSON.parse(res); //将字符串转成json
opt.success.call(xhr, res);
}
}
} else {
if (opt.error && opt.error instanceof Function) {
opt.error.call(xhr, res);
}
}
};
}
```
Ajax 的推荐链接<https://segmentfault.com/a/1190000006669043>
## 跨域通信的几种方式
方式如下
- 1JSONP
- 2WebSocket
- 3CORS
- 4Hash
- 5postMessage
上面这五种方式在面试时都要说出来
### 1JSONP
面试会问JSONP的原理是什么怎么实现的
在CORS和postMessage以前我们一直都是通过JSONP来做跨域通信的
**JSONP的原理**通过`<script>`标签的异步加载来实现的比如说实际开发中我们发现head标签里可以通过`<script>`标签的src里面放url加载很多在线的插件这就是用到了JSONP
**JSONP的实现**
比如说客户端这样写
```html
<script src="http://www.smyhvae.com/?data=name&callback=myjsonp"></script>
```
上面的src中`data=name`是get请求的参数`myjsonp`是和后台约定好的函数名
服务器端这样写
```bash
myjsonp({
data: {}
})
```
于是本地要求创建一个myjsonp **全局函数**才能将返回的数据执行出来
**实际开发中前端的JSONP是这样实现的**
```html
<script>
var util = {};
//定义方法:动态创建 script 标签
/**
* [function 在页面中注入js脚本]
* @param {[type]} url [description]
* @param {[type]} charset [description]
* @return {[type]} [description]
*/
util.createScript = function (url, charset) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
charset && script.setAttribute('charset', charset);
script.setAttribute('src', url);
script.async = true;
return script;
};
/**
* [function 处理jsonp]
* @param {[type]} url [description]
* @param {[type]} onsucess [description]
* @param {[type]} onerror [description]
* @param {[type]} charset [description]
* @return {[type]} [description]
*/
util.jsonp = function (url, onsuccess, onerror, charset) {
var callbackName = util.getName('tt_player'); //事先约定好的 函数名
window[callbackName] = function () { //根据回调名称注册一个全局的函数
if (onsuccess && util.isFunction(onsuccess)) {
onsuccess(arguments[0]);
}
};
var script = util.createScript(url + '&callback=' + callbackName, charset); //动态创建一个script标签
script.onload = script.onreadystatechange = function () { //监听加载成功的事件,获取数据
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null;
// 移除该script的 DOM 对象
if (script.parentNode) {
script.parentNode.removeChild(script);
}
// 删除函数或变量
window[callbackName] = null; //最后不要忘了删除
}
};
script.onerror = function () {
if (onerror && util.isFunction(onerror)) {
onerror();
}
};
document.getElementsByTagName('head')[0].appendChild(script); //往html中增加这个标签目的是把请求发送出去
};
</script>
```
### 2WebSocket
WebSocket的用法如下
```javascript
//
var ws = new WebSocket('wss://echo.websocket.org'); //创建WebSocket的对象。参数可以是 ws 或 wss后者表示加密。
//把请求发出去
ws.onopen = function (evt) {
console.log('Connection open ...');
ws.send('Hello WebSockets!');
};
//对方发消息过来时,我接收
ws.onmessage = function (evt) {
console.log('Received Message: ', evt.data);
ws.close();
};
//关闭连接
ws.onclose = function (evt) {
console.log('Connection closed.');
};
```
Websocket的推荐链接<http://www.ruanyifeng.com/blog/2017/05/websocket.html>
面试一般不会让你写这个代码一般是考察你是否了解 WebSocket概念知道有这么回事即可
### 3CORS
CORS 可以理解成是**既可以同步也可以异步**的Ajax
fetch 是一个比较新的API用来实现CORS通信用法如下
```javascript
// url必选options可选
fetch('/some/url/', {
method: 'get',
}).then(function (response) { //类似于 ES6中的promise
}).catch(function (err) {
// 出错了,等价于 then 的第二个参数,但这样更好用更直观
});
```
- CORS的推荐链接<http://www.ruanyifeng.com/blog/2016/04/cors.html>
推荐链接里有详细的配置
另外如果面试官问CORS为什么支持跨域的通信
答案跨域时浏览器会拦截Ajax请求并在http头中加Origin
### 4Hash
url的`#`后面的内容就叫Hash**Hash的改变页面不会刷新**这就是用 Hash 做跨域通信的基本原理
补充url的`?`后面的内容叫SearchSearch的改变会导致页面刷新因此不能做跨域通信
**使用举例**
**场景**我的页面 A 通过iframe或frame嵌入了跨域的页面 B
现在我这个A页面想给B页面发消息怎么操作呢
1首先在我的A页面中
```javascript
//伪代码
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'jsonString'; //我们可以把JS 对象,通过 JSON.stringify()方法转成 json字符串发给 B
```
2然后在B页面中
```javascript
// B中的伪代码
window.onhashchange = function () { //通过onhashchange方法监听url中的 hash 是否发生变化
var data = window.location.hash;
};
```
### 5postMessage()方法
> H5中新增的postMessage()方法可以用来做跨域通信既然是H5中新增的那就一定要提到
**场景**窗口 A (`http:A.com`)向跨域的窗口 B (`http:B.com`)发送信息步骤如下
1在A窗口中操作如下向B窗口发送数据
```javascript
// 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
Bwindow.postMessage('data', 'http://B.com'); //这里强调的是B窗口里的window对象
```
2在B窗口中操作如下
```javascript
// 在窗口B中监听 message 事件
Awindow.addEventListener('message', function (event) { //这里强调的是A窗口里的window对象
console.log(event.origin); //获取 url。这里指http://A.com
console.log(event.source); //获取A window对象
console.log(event.data); //获取传过来的数据
}, false);
```
## 我的公众号
想学习<font color=#0000ff>**代码之外的技能**</font>****id`qianguyihao`
扫一扫你将发现另一个全新的世界而这将是一场美丽的意外
![](http://img.smyhvae.com/2016040102.jpg)

View File

@@ -0,0 +1,203 @@
## 前言
面试中的安全问题明确来说就两个方面
- CSRF基本概念攻击方式防御措施
- XSS基本概念攻击方式防御措施
这两个问题一般不会问太难
有人问SQL注入算吗答案这个其实跟前端的关系不是很大
## CSRF
问的不难一般问
- CSRF的基本概念缩写全称
- 攻击原理
- 防御措施
如果把**攻击原理****防御措施**掌握好基本没什么问题
### 1CSRF的基本概念缩写全称
CSRFCross-site request forgery**跨站请求伪造**
PS中文名一定要记住英文全称如果记不住也拉倒
### 2CSRF的攻击原理
![](http://img.smyhvae.com/20180307_1735.png)
用户是网站A的注册用户且登录进去于是网站A就给用户下发cookie
从上图可以看出要完成一次CSRF攻击受害者必须满足两个必要的条件
1登录受信任网站A并在本地生成Cookie如果用户没有登录网站A那么网站B在诱导的时候请求网站A的api接口时会提示你登录
2在不登出A的情况下访问危险网站B其实是利用了网站A的漏洞
我们在讲CSRF时一定要把上面的两点说清楚
温馨提示一下cookie保证了用户可以处于登录状态但网站B其实拿不到 cookie
举个例子前段时间里微博网站有个api接口有漏洞导致很多用户的粉丝暴增
### 3CSRF如何防御
**方法一Token 验证**用的最多
1服务器发送给客户端一个token
2客户端提交的表单中带着这个token
3如果这个 token 不合法那么服务器拒绝这个请求
**方法二隐藏令牌**
token 隐藏在 http head头中
方法二和方法一有点像本质上没有太大区别只是使用方式上有区别
**方法三Referer 验证**
Referer 指的是页面请求来源意思是**只接受本站的请求服务器才做响应**如果不是就拦截
## XSS
### 1XSS的基本概念
XSSCross Site Scripting**跨域脚本攻击**
接下来我们详细讲一下 XSS 的内容
> 预备知识HTTPCookieAjax
### XSS的攻击原理
XSS攻击的核心原理是不需要你做任何的登录认证它会通过合法的操作比如在url中输入在评论框中输入向你的页面注入脚本可能是jshmtl代码块等
最后导致的结果可能是
- 盗用Cookie
- 破坏页面的正常结构插入广告等恶意内容
- D-doss攻击
### XSS的攻击方式
- 1反射型
发出请求时XSS代码出现在url中作为输入提交到服务器端服务器端解析后响应XSS代码随响应内容一起传回给浏览器最后浏览器解析执行XSS代码这个过程像一次反射所以叫反射型XSS
- 2存储型
存储型XSS和反射型XSS的差别在于提交的代码会存储在服务器端数据库内存文件系统等下次请求时目标页面时不用再提交XSS代码
### XSS的防范措施encode + 过滤
XSS的防范措施主要有三个
**1编码**
对用户输入的数据进行`HTML Entity`编码
如上图所示把字符转换成 转义字符
Encode的作用是将`$var`等一些字符进行转化使得浏览器在最终输出结果上是一样的
比如说这段代码
```
<script>alert(1)</script>
```
若不进行任何处理则浏览器会执行alert的js操作实现XSS注入
进行编码处理之后L在浏览器中的显示结果就是`<script>alert(1)</script>`实现了将$var作为纯文本进行输出且不引起JavaScript的执行
参考链接[4类防御XSS的有效方法](https://www.jianshu.com/p/599fcd03fd3b)
**2过滤**
- 移除用户输入的和事件相关的属性如onerror可以自动触发攻击还有onclick等总而言之过滤掉一些不安全的内容
- 移除用户输入的Style节点Script节点Iframe节点尤其是Script节点它可是支持跨域的呀一定要移除
**3校正**
- 避免直接对`HTML Entity`进行解码
- 使用`DOM Parse`转换校正不配对的DOM标签
备注我们应该去了解一下`DOM Parse`这个概念它的作用是把文本解析成DOM结构
比较常用的做法是通过第一步的编码转成文本然后第三步转成DOM对象然后经过第二步的过滤
**还有一种简洁的答案**
首先是encode如果是富文本就白名单
## CSRF XSS 的区别
面试官还可能喜欢问二者的区别
区别一
- CSRF需要用户先登录网站A获取 cookie
- XSS不需要登录
区别二原理的区别
- CSRF是利用网站A本身的漏洞去请求网站A的api
- XSS是向网站 A 注入 JS代码然后执行 JS 里的代码篡改网站A的内容
## 其他
### XSS
关于XSS推荐几个网站
- <http://html5sec.org/>
里面列出了很多XSS的例子可以长见识如果你专门研究XSS可以看看
- [FreeBuf网站上的专栏作者Black-Hole](http://www.freebuf.com/author/black-hole)
比如他的第一篇文章就讲到了[XSS的原理分析与解剖](http://www.freebuf.com/articles/web/40520.html)。有句话摘抄如下弹窗只是测试xss的存在性和使用性。
比如这个人还有篇文章写[自动化检测CSRF第一章](http://www.freebuf.com/articles/web/107207.html)。大公司做网站一般会做嗅探服务比如自动化工具做CSRF的检测、自动化的方式控制安全风险
另外可能还有些工具可以扫描代码本身有没有一些安全问题
- [GitHub | Cure53](https://github.com/cure53)
这是GitHub上的一个德国组织
上面的项目都跟安全相关有些仓库是可以直接运行的如果你不需要定制就可以直接用别人的没必要自己写XSS库XSS的过滤之类的避免麻烦

View File

@@ -0,0 +1,104 @@
## 前言
算法主要包括
- 1排序
排序一定要准备
- 2堆栈队列链表
队列和链表可以不准备但是堆栈一定要准备
一个小技巧JS的数组本身就具备堆栈和队列的特性比如poppushshiftunshift这四个api本身就帮我们实现了堆栈和队列
堆栈先进后出
- 3递归
递归是一定不能偷懒的算法比较难的时候一般要用到递归
- 4波兰式和逆波兰式
**总结**
比如阿里如果基础题答的很好但是算法不会那可能通不过
还有金融类的必考算法比如阿里云里面的业务就是算法的所以肯定考算法
## 排序
上面的排序这么多我们要记住下面这三个
- 快速排序<https://segmentfault.com/a/1190000009426421>
- 选择排序<https://segmentfault.com/a/1190000009366805>
- 希尔排序<https://segmentfault.com/a/1190000009461832>
如果你还要学一个那就是**冒泡排序**
题目中会给你一个算法题 排序只是其中一个步骤而且并不会指定你要求用哪种排序
## 堆栈队列链表
参考链接
- <https://juejin.im/entry/58759e79128fe1006b48cdfd>
上面这个链接是转载的原创博主的系列文章是
- [数组队列链表](http://huang303513.github.io/2016/12/08/Javascript%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95(%E4%B8%80).html)
- [排序](http://huang303513.github.io/2016/12/19/Javascript%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95(%E5%9B%9B).html)
## 递归
参考链接
- [JavaScript中的递归](https://segmentfault.com/a/1190000009857470)
递归理解起来不难但是用的时候很难因为你没抓住他的本质递归的终止条件是什么参数是怎么传递的一定要搞清楚
很多人说我知道这道题是考递归但是我就是不知道该怎么写这个面试官很无奈
## 波兰式和逆波兰式
> 如果复习时间很紧张这部分也不用准备了也不是所有的公司都会问
推荐链接
- 理论<http://www.cnblogs.com/chenying99/p/3675876.html>
- 源码<https://github.com/Tairraos/rpn.js/blob/master/rpn.js>
## 总结
如果实在答不来就说这个算法我不是很会只知道一些基本概念
如果第一面就碰到算法题这个公司不用去了说明这个公司是招算法的不是招前端的

View File

@@ -0,0 +1,242 @@
## 前言
面试时关于`同步和异步`可能会问以下问题
- 同步和异步的区别是什么分别举一个同步和异步的例子
- 一个关于 setTimeout 的笔试题
- 前端使用异步的场景哪些
面试时关于`js运行机制`需要注意以下几个问题
- 如何理解JS的**单线程**
- 什么是**任务队列**
- 什么是 EventLoop
- 理解哪些语句会放入异步任务队列
- 理解语句放入异步任务队列的**时机**
## JS的异步和单线程
> 因为是单线程所以必须异步
我们通过题目来解释以下
### 题目一异步
现有如下代码
```javascript
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
console.log(3);
console.log(4);
```
上面的代码中我们很容易知道打印的顺序是`1342`因为你会想到要等一秒之后再打印`2`
可如果我把延时的时间从`1000`改成`0`
```javascript
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
console.log(3);
console.log(4);
```
上方代码中打印的顺序仍然是`1342`这是为什么呢我们来分析一下
**总结**
js 是单线程同一时间只能做一件事而且有一个**任务队列**全部的同步任务执行完毕后再来执行异步任务第一行代码和最后一行代码是同步任务但是**`setTimeout`是异步任务**
于是执行的顺序是
- 先执行同步任务`console.log(1)`
- 遇到异步任务`setTimeout`**挂起**
- 执行同步任务`console.log(3)`
- **全部的同步任务执行完毕后再来执行异步任务**`console.log(2)`
很多人会把这个题目答错这是因为他们不懂 js 的运行机制
注意上面那句话同步任务执行完毕后再来执行异步任务也就是说**如果同步任务没有执行完异步任务是不会执行的**为了解释这句话我们来看下面这个例子
### 题目二异步
现有如下代码
```javascript
console.log('A');
while (1) {
}
console.log('B');
```
我们很容易想到上方代码的打印结果是`A`因为while是同步任务代码会陷入死循环里出不来自然也就无法打印`B`可如果我把代码改成下面的样子
```javascript
console.log('A');
setTimeout(function () {
console.log('B');
})
while (1) {
}
```
上方代码的打印结果仍然是`A`因为while是同步任务setTimeout是异步任务所以还是那句话**如果同步任务没有执行完队列里的异步任务是不会执行的**
### 题目三同步
```javascript
console.log('A');
alert('haha'); //1秒之后点击确认
console.log('B');
```
`alert`函数是同步任务我只有点击了确认才会继续打印`B`
### 同步和异步的对比
我们在上面列举了异步和同步的例子现在来描述一下区别重要
因为`setTimeout`**异步任务**所以程序并不会卡在那里而是继续向下执行即使settimeout设置了倒计时一万秒但是`alert`函数是**同步**任务程序会**卡在那里**如果它没有执行后面的也不会执行卡在那里自然也就造成了**阻塞**
### 前端使用异步的场景
什么时候需要**等待**就什么时候用异步
- 定时任务setTimeout定时炸弹setInterval循环执行
- 网络请求ajax请求动态`<img>`加载
- 事件绑定比如说按钮绑定点击事件之后用户爱点不点我们不可能卡在按钮那里什么都不做所以应该用异步
- ES6中的Promise
代码举例
```javascript
console.log('start');
var img = document.createElement('img');
img.onload = function () {
console.log('loaded');
}
img.src = '/xxx.png';
console.log('end');
```
上图中先打印`start`然后执行`img.src = '/xxx.png'`然后打印`end`最后打印`loaded`
## 任务队列和Event Loop事件循环
### 任务队列
所有任务可以分成两种一种是同步任务synchronous另一种是异步任务asynchronous同步任务指的是在主线程上排队执行的任务只有前一个任务执行完毕才能执行后一个任务异步任务指的是不进入主线程而进入"任务队列"task queue的任务只有"任务队列"通知主线程某个异步任务可以执行了该任务才会进入主线程执行
总结**只要主线程空了就会去读取"任务队列"这就是JavaScript的运行机制**重要
### Event Loop
主线程从"任务队列"中读取事件这个过程是循环不断的所以整个的这种运行机制又称为Event Loop事件循环
![](http://img.smyhvae.com/20180310_1840.png)
在理解Event Loop时要理解两句话
- 理解哪些语句会放入异步任务队列
- 理解语句放入异步任务队列的**时机**
### 容易答错的题目
```javascript
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
```
很多人以为上面的题目答案是`0,1,2,3`其实正确的答案是`3,3,3,3`
分析for 循环是同步任务setTimeout是异步任务for循环每次遍历的时候遇到settimeout就先暂留着等同步任务全部执行完毕此时i已经等于3了再执行异步任务
我们把上面的题目再加一行代码最终代码如下
```javascript
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
console.log(i);
```
如果我们约定用箭头表示其前后的两次输出之间有 1 秒的时间间隔而逗号表示其前后的两次输出之间的时间间隔可以忽略代码实际运行的结果该如何描述可能会有两种答案
- A. 60% 的人会描述为`3 -> 3 -> 3 -> 3`即每个 3 之间都有 1 秒的时间间隔
- B. 40% 的人会描述为`3 -> 3,3,3`即第 1 3 直接输出1 秒之后连续输出 3 3
循环执行过程中几乎同时设置了 3 个定时器这些定时器都会在 1 秒之后触发而循环完的输出是立即执行的显而易见正确的描述是 B
上面这个题目的参考链接
- [80% 应聘者都不及格的 JS 面试题](https://juejin.im/post/58cf180b0ce4630057d6727c)
- [深入浅出Javascript事件循环机制()](https://zhuanlan.zhihu.com/p/26229293)

View File

@@ -0,0 +1,277 @@
> 本文最初发表于[博客园](https://www.cnblogs.com/smyhvae/p/8550195.html),并在[GitHub](https://github.com/qianguyihao/Web)上持续更新**前端的系列文章**。欢迎在GitHub上关注我一起入门和进阶前端。
> 以下是正文
## 前言
提升页面性能优化的方法有哪些
- 1资源压缩合并减少http请求
- 2**非核心代码异步加载** --> 异步加载的方式 --> 异步加载的区别
如果回答出`非核心代码异步加载`就会层层深入
- 3利用浏览器缓存 --> 缓存的分类 --> 缓存的原理
**缓存**是所有性能优化的方式中最重要的一步这个一定要答好重要
有的人可能会回答local storage 和session storage其实不是这个浏览器缓存和存储不是一回事
- 4使用CDN
浏览器第一次打开页面时缓存是起不了作用的CDN这一条一定要说出来
- 5DNS预解析
## 资源压缩合并减少http请求
- 合并图片css spritesCSS和JS文件合并CSS和JS文件压缩
- 图片较多的页面也可以使用 lazyLoad 等技术进行优化
- 精灵图等
## 非核心代码异步加载
异步加载的方式这里不说框架只说原理
- 动态脚本加载
- defer
- async
### 动态脚本加载
使用document.createElement创建一个script标签`document.createElement('script')`然后把这个标签加载到body上面去
参考链接
- [javascript 异步加载](https://www.jianshu.com/p/13cf23a90328) 动态脚本加载的那部分代码,看不太懂。
### defer
通过异步的方式加载defer1.js文件
```html
<script src="./defer1.js" defer></script>
```
### async
> HTmL5新增特性
通过异步的方式加载async1.js文件
```html
<script src="./async1.js" async></script>
```
### defer和async的区别
- defer在HTML解析完之后才会执行如果是多个则按照加载的顺序依次执行
- async在加载完之后立即执行如果是多个执行顺序和加载顺序无关
代码举例
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!--通过异步的方式引入两个外部的js文件-->
<script src="./defer1.js" defer></script>
<script src="./defer2.js" defer></script>
</head>
<body>
<script>
console.log('同步任务');
</script>
</body>
</html>
```
上方打印的结果是
```
同步任务
defer1
defer2
```
因为defer的加载是有顺序的所以两个引入defer文件按顺序执行如果把引入的文件改为async的方式加载打印的结果可能是
```
同步任务
async2
async1
```
参考链接
- [浅谈script标签的defer和async](https://segmentfault.com/a/1190000006778717)
## 利用浏览器缓存
**缓存**资源文件比如图片**本地的硬盘**里存有副本浏览器下次请求的时候可能直接从本地磁盘里读取而不会重新请求图片的url
缓存分为
- 强缓存
- 协商缓存
### 强缓存
**强缓存**不用请求服务器直接使用本地的缓存
强缓存是利用 http 响应头中的**`Expires`****`Cache-Control`**实现的重要
浏览器第一次请求一个资源时服务器在返回该资源的同时会把上面这两个属性放在response header中比如
![](http://img.smyhvae.com/20180310_2310.png)
**注意**这两个response header属性可以只启用一个也可以同时启用当response header中Expires和Cache-Control同时存在时**Cache-Control的优先级高于Expires**
下面讲一下二者的区别
**1`Expires`**服务器返回的**绝对时间**
是较老的强缓存管理 response header浏览器再次请求这个资源时先从缓存中寻找找到这个资源后拿出它的Expires跟当前的请求时间比较如果请求时间在Expires的时间之前就能命中缓存否则就不行
如果缓存没有命中浏览器直接从服务器请求资源时Expires Header在重新请求的时候会被更新
**缺点**
由于`Expires`是服务器返回的一个绝对时间存在的问题是服务器的事件和客户端的事件可能不一致在服务器时间与客户端时间相差较大时缓存管理容易出现问题比如随意修改客户端时间就能影响缓存命中的结果所以在http1.1提出了一个新的response header就是Cache-Control
**2`Cache-Control`**服务器返回的**相对时间**
http1.1中新增的 response header浏览器第一次请求资源之后在接下来的相对时间之内都可以利用本地缓存超出这个时间之后则不能命中缓存重新请求时`Cache-Control`会被更新
### 协商缓存
**协商缓存**浏览器发现本地有资源的副本但是不太确定要不要使用于是去问问服务器
当浏览器对某个资源的请求没有命中强缓存也就是说超出时间了就会发一个请求到服务器验证协商缓存是否命中
协商缓存是利用的是两对Header
- 第一对`Last-Modified``If-Modified-Since`
- 第二对`ETag``If-None-Match`
ETagEntity Tag被请求变量的实体值
**1`Last-Modified``If-Modified-Since`**过程如下
1浏览器第一次请求一个资源服务器在返回这个资源的同时会加上`Last-Modified`这个 response header这个header表示这该资源在服务器上的最后修改时间
![](http://img.smyhvae.com/20180311_1715.png)
2浏览器再次请求这个资源时会加上`If-Modified-Since`这个 request header这个header的值就是上一次返回的`Last-Modified`的值
![](http://img.smyhvae.com/20180311_1716.png)
3服务器收到第二次请求时会比对浏览器传过来的`If-Modified-Since`和资源在服务器上的最后修改时间`Last-Modified`判断资源是否有变化如果没有变化则返回304 Not Modified但不返回资源内容此时服务器不会返回 Last-Modified 这个 response header如果有变化就正常返回资源内容继续重复整个流程这是服务器返回304时的response header
![](http://img.smyhvae.com/20180311_1720.png)
4浏览器如果收到304的响应就会从缓存中加载资源
**缺点**
`Last-Modified``If-Modified-Since`一般来说都是非常可靠的但面临的问题是
- **服务器上的资源变化了但是最后的修改时间却没有变化**
- 如果服务器端在一秒内修改文件两次但产生的`Last-Modified`却只有一个值
这一对header就无法解决这种情况于是下面这一对header出场了
**2`ETag``If-None-Match`**过程如下
1浏览器第一次请求一个资源服务器在返回这个资源的同时会加上`ETag`这个 response header这个header是服务器根据当前请求的资源生成的**唯一标识**这个唯一标识是一个字符串只要资源有变化这个串就不同跟最后修改时间无关所以也就很好地补充了`Last-Modified`的不足如下
![](http://img.smyhvae.com/20180311_1735.png)
2浏览器再次请求这个资源时会加上`If-None-Match`这个 request header这个header的值就是上一次返回的`ETag`的值
![](http://img.smyhvae.com/20180311_1737.png)
3服务器第二次请求时会对比浏览器传过来的`If-None-Match`和服务器重新生成的一个新的`ETag`判断资源是否有变化如果没有变化则返回304 Not Modified但不返回资源内容此时由于ETag重新生成过response header中还会把这个ETag返回即使这个ETag并无变化如果有变化就正常返回资源内容继续重复整个流程这是服务器返回304时的response header
![](http://img.smyhvae.com/20180311_1740.png)
4浏览器如果收到304的响应就会从缓存中加载资源
提示如果面试官问你与浏览器缓存相关的http header有哪些你能写出来吗这是一个亮点
参考链接
- [浏览器缓存知识小结及应用](https://www.cnblogs.com/lyzg/p/5125934.html)[荐]
## 使用CDN
怎么最快地让用户请求资源一方面是让资源在传输的过程中变小另外就是CDN
要注意浏览器第一次打开页面的时候浏览器缓存是起不了作任何用的使用CDN效果就很明显
## DNS预解析dns-prefetch
通过 DNS 预解析来告诉浏览器未来我们可能从某个特定的 URL 获取资源当浏览器真正使用到该域中的某个资源时就可以尽快地完成 DNS 解析
**第一步**打开或关闭DNS预解析
你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头或是在文档中使用值为 http-equiv 的meta标签
```html
<meta http-equiv="x-dns-prefetch-control" content="on">
```
需要说明的是在一些高级浏览器中页面中所有的超链接`<a>`标签默认打开了DNS预解析但是如果页面中采用的https协议很多浏览器是默认关闭了超链接的DNS预解析如果加了上面这行代码则表明强制打开浏览器的预解析如果你能在面试中把这句话说出来则一定是你出彩的地方
**第二步**对指定的域名进行DNS预解析
如果我们将来可能从 smyhvae.com 获取图片或音频资源那么可以在文档顶部的 <head> 标签中加入以下内容
```html
<link rel="dns-prefetch" href="http://www.smyhvae.com/">
```
当我们从该 URL 请求一个资源时就不再需要等待 DNS 解析的过程该技术对使用第三方资源特别有用
参考链接
- [前端性能优化 - 资源预加载](http://bubkoo.com/2015/11/19/prefetching-preloading-prebrowsing/)[荐]
- [DNS预解析详解](https://www.xuanfengge.com/dns-prefetching-analysis.html)
## 我的公众号
想学习<font color=#0000ff>**代码之外的技能**</font>****id`qianguyihao`
扫一扫你将发现另一个全新的世界而这将是一场美丽的意外
![](http://img.smyhvae.com/2016040102.jpg)

View File

@@ -0,0 +1,185 @@
## 前言
错误监控包含的内容是
- 前端错误的分类
- 每种错误的捕获方式
- 上报错误的基本原理
面试时可能有两种问法
- 如何监测 js 错误开门见山的方式
- 如何保证**产品质量**其实问的也是错误监控
## 前端错误的分类
包括两种
- 即时运行错误代码错误
- 资源加载错误
## 每种错误的捕获方式
### 即时运行错误的捕获方式
**方式1**try ... catch
这种方式要部署在代码中
**方式2**`window.onerror`函数这个函数是全局的
```
window.onerror = function(msg, url, row, col, error) { ... }
```
参数解释
- msg为异常基本信息
- source为发生异常Javascript文件的url
- row为发生错误的行号
方式二中的`window.onerror`是属于DOM0的写法我们也可以用DOM2的写法`window.addEventListener("error", fn);`也可以
**问题延伸1**
`window.onerror`默认无法捕获**跨域**的js运行错误捕获出来的信息如下基本属于无效信息
比如说我们的代码想引入B网站的`b.js`文件怎么捕获它的异常呢
**解决办法**在方法二的基础之上做如下操作
1`b.js`文件里加入如下 response header表示允许跨域或者世界给静态资源`b.js`加这个 response header
```
Access-Control-Allow-Origin: *
```
2引入第三方的文件`b.js``<script>`标签中增加`crossorigin`属性
参考链接
- [window.onerror的总结](https://www.jianshu.com/p/315ffe6797b8)
- [前端代码异常日志收集与监控](http://www.cnblogs.com/hustskyking/archive/2015/08/20/fe-monitor.html)
- [捕获页面中全局Javascript异常](https://foio.github.io/javascript-global-exceptions/)
**问题延伸2**
只靠方式二中的`window.onerror`是不够的因为我们无法获取文件名是什么不知道哪里出了错误解决办法**堆栈**信息作为msg打印出来堆栈里很详细
### 资源加载错误的捕获方式
上面的window.onerror只能捕获即时运行错误无法捕获资源加载错误原理是资源加载错误并不会向上冒泡object.onerror捕获后就会终止不会冒泡给window所以window.onerror并不能捕获资源加载错误
**方式1**object.onerrorimg标签script标签等节点都可以添加onerror事件用来捕获资源加载的错误
**方式2**performance.getEntries可以获取所有已加载资源的加载时长通过这种方式可以间接的拿到没有加载的资源错误
举例
浏览器打开一个网站在Console控制台下输入
```
performance.getEntries().forEach(function(item){console.log(item.name)})
```
或者输入
```
performance.getEntries().forEach(item=>{console.log(item.name)})
```
上面这个api返回的是数组既然是数组就可以用forEach遍历打印出来的资源就是**已经成功加载**的资源
![](http://img.smyhvae.com/20180311_2030.png)
再输入`document.getElementsByTagName('img')`就会显示出所有**需要加载**的的img集合
于是`document.getElementsByTagName('img')`获取的资源数组减去通过`performance.getEntries()`获取的资源数组剩下的就是没有成功加载的这种方式可以间接捕获到资源加载错误
这种方式非常有用一定要记住
**方式3**Error事件捕获
源加载错误虽然会阻止冒泡但是不会阻止捕获我们可以在捕获阶段绑定error事件例如
![](http://img.smyhvae.com/20180311_2040.png)
**总结**如果我们能回答出后面的两种方式面试官对我们的印象会大大增加既可以体现出我们对错误监控的了解还可以体现出我们对事件模型的掌握
参考链接
- [前端错误监控原理与实战](http://www.cnblogs.com/gaoning/p/7928497.html) (作者的这篇文章参考了面试内容)
## 错误上报的两种方式
**方式一**采用Ajax通信的方式上报此方式虽然可以上报错误但是我们并不采用这种方式
**方式二**利用Image对象上报推荐网站的监控体系都是采用的这种方式
方式二的实现方式如下
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
//通过Image对象进行错误上报
(new Image()).src = 'http://smyhvae.com/myPath?badjs=msg'; // myPath表示上报的路径我要上报到哪里去。后面的内容是自己加的参数。
</script>
</body>
</html>
```
打开浏览器效果如下
![](http://img.smyhvae.com/20180311_2055.png)
上图中红色那一栏表明我的请求已经发出去了点进去看看
![](http://img.smyhvae.com/20180311_2057.png)
这种方式不需要借助第三方的库一行代码即可搞定

View File

@@ -0,0 +1,167 @@
博客园一年经验初探阿里巴巴前端社招
文章来源<https://www.cnblogs.com/fsyz/p/8298921.html>
一般阿里社招都是招3-5年的P6+高级工程师当初自己一年经验也没有想过有这个面试机会
虽然没想着换工作但是经常关注一些招聘网站的信息某一天在某boss上有个人找我叫我发一下简历我一看是阿里的某技术专家虽然之前也有阿里的在某boss上给我要简历但是我深知自己经验不足然后给boss说我是16届的只有一年经验然后就没有然后了这次我依然这么回复但是这boss说没关系他喜欢基础好的让我可以试一试于是我也抱着试一试的心态发了简历
简历发过去之后boss就给我打了电话让我简单的介绍一下自己我就噼里啪啦说了一些还说了一些题外话然后boss就开始问我问题
由于面了四轮所以最开始的面试记忆有点模糊了细细回想又感觉记忆犹新
1.电话初探
1.说一下你了解CSS盒模型
我就说了一下IE的怪异盒模型和标注浏览器的盒模型然后可以通过box-sizing属性控制两种盒模型的变换
2.说一下box-sizing的应用场景
这个也不难简单说了一两个应用场景具体就不一一细说了
3.说一下你了解的弹性FLEX布局.
这个我也比较了解各种概念和属性能想到的说了一大堆也扯到了Grid布局基本这个也没啥问题
4.说一下一个未知宽高元素怎么上下左右垂直居中
说了一下flex弹性布局的实现说了一下兼容性扯到了postcss的一些东西然后说了一下常规的兼容性比较好的实现
5.说一下原型链对象构造函数之间的一些联系
这个我之前写过相关的文章自己也有比较深入的理解所以这个也不在话下噼里啪啦说了一大堆也不知道面试官听得咋样
6.DOM事件的绑定的几种方式
说了三种然后说了一些冒泡默认事件以及DOM2DOM3级的一些标准
7.说一下你项目中用到的技术栈以及觉得得意和出色的点以及让你头疼的点怎么解决的
这个因人而异开放性问题主要考察平时项目的一些积累吧这个我回答感觉也比较ok
8.有没有了解http2.0,websocket,https说一下你的理解以及你所了解的特性
这个我看过一些文章但是没有什么印象扯了一些概念但是回答的不是很深
第一轮电话初探大约面了50分钟就记起来这么多还有一些细节问题可能淡忘了总体来说面的都是以基础为主然后boss说把我简历推荐给内部进行正式的社招流程
一轮技术面
然后当天晚上一个女的面试官就给我打电话了说八点半进行下一轮技术面试没想到效率这么快我都没怎么准备
这次就直接省略自我介绍了
1.webpack的入口文件怎么配置多个入口怎么分割啥的我也没太听清楚
这个自己就说了一下自己的理解以及自己用node写的多入口怎么配置然后面试官说不是多入口配置然后我又说了一下自己的理解然后这题就过了
2.我看到你的项目用到了Babel的一个插件transform-runtime以及stage-2你说一下他们的作用
这个我也还算比较了解就说了一下ES的一些API比如generator啥的默认不转换只转换语法需要这个来转换然后说profill啥的扯了一下stage-1stage-2stage-3这个问题回答还算清楚
3.我看到你的webpack配置用到webpack.optimize.UglifyJsPlugin这个插件有没有觉得压缩速度很慢有什么办法提升速度
这个我主要回答了一下我之前也没怎么了解一个想到是缓存原理压缩只重新压缩改变的还有就是减少冗余的代码压缩只用于生产阶段然后面试官问还有呢我就说还可以从硬件上提升可以得到质的飞跃比如换台I9处理器的电脑
4.简历上看见你了解http协议说一下200和304的理解和区别
这个噼里啪啦说了一堆协商缓存和强制缓存的区别流程还有一些细节提到了expires,Cache-Control,If-none-match,Etag,last-Modified的匹配和特征这一块之前有过比较详细的了解所以还是应答如流
5.DOM事件中target和currentTarget的区别
这个没答上来
6.说一下你平时怎么解决跨域的以及后续JSONP的原理和实现以及cors怎么设置
我就说了一下Jason和cors,然后问我JSONP的原理以及cors怎么设置这一块自己也实践过所以还是对答如流的
7.说一下深拷贝的实现原理
这个也还好就是考虑的细节不是很周全先是说了一种JSON.stringify和JSON.parse的实现以及这种实现的缺点主要就是非标准JSOn格式无法拷贝以及兼容性问题然后问了我有么有用过IE8的一个什么JSON框架我也不记得是什么了因为我压根没听过然后说了一下尾递归实现深拷贝的原理还问了我typeof null是啥这个当然是Object
8.说一下项目中觉得可以改进的地方以及做的很优秀的地方
这个也是因人而异开放性问题大致扯了一下自己的经历也还OK
最后问了有什么需要问的地方面试到这里基本就结束了大约面了一个多钟头还是蛮累的总体来说回答的广度和深度以及细节都还算OK觉得这轮面试基本没什么悬念
二轮技术面
过了几天接到阿里另一个面试官的电话上一轮面试通过了这次是二轮技术面说估计一个钟头这次依然跳过自我介绍之类的直奔主题
1.有没有自己写过webpack的loader,他的原理以及啥的记得也不太清楚
这个我就说了一下然后loader配置啥的也还ok
2.有没有去研究webpack的一些原理和机制怎么实现的
这个我简单说了一下我自己了解的因为这一块我也没深入去研究所以说的应该比较浅
3.babel把ES6转成ES5或者ES3之类的原理是什么有没有去研究
这一块我说了一下自己的思路大致也还OK我也没去深入研究怎么转换的之前好像看过类似的文章自己也只观察过转换之后的代码是啥样的至于怎么转换的规则真的没去深入观察
4.git大型项目的团队合作以及持续集成啥的
这里我就说了一下自己了解的git flow方面的东西因为没有实战经验所以我就选择性说明了这一块的不熟练然后面试官也没细问
5.什么是函数柯里化以及说一下JS的API有哪些应用到了函数柯里化的实现
这个我就说了一下函数柯里化一些了解以及在函数式编程的应用最后说了一下JS中bind函数和数组的reduce方法用到了函数柯里化
6.ES6的箭头函数this问题以及拓展运算符
这一块主要是API和概念的问题扯了一些规范以及严格模式下其他情况this只想问题
7.JS模块化Commonjs,UMD,CMD规范的了解以及ES6的模块化跟其他几种的区别以及出现的意义
这个也是说了一下自己的理解和认知自己对模块化历史以及一些规范都有所涉猎这一块也还凑合
8.说一下Vue实现双向数据绑定的原理以及vue.js和react.js异同点如果让你选框架你怎么怎么权衡这两个框架分析一下
主要是发布订阅的设计模式还有就是ES5的Object.defineProperty的getter和setter机制然后顺便扯了一下Angular的脏检测以及alvon.js最先用到这种方式然后扯了一下vue.js和react.js异同点权衡框架选择调研分析之类噼里啪啦说了一大堆
9.我看你也写博客说一下草稿的交互细节以及实现原理
这一款就按照自己用过简书或者掘金SG这类草稿的体验详细说了一下这个开放性问题说到点基本就OK
最后面试官问我有什么想问的吗面试到这里基本就结束了差不多面了一个小时说过几天就会给答复如果过了就会去阿里园区进行下一轮的技术面
三轮技术面
上一轮发挥感觉没前两轮发挥好所以还是有点不自信的没想到第三天后就来电话了通知我去阿里园区面试
因为阿里西溪园区距离我不到十公里我就踩着共享单车一点钟就出发了天气比较热飘在路上百感交集身边一辆法拉利轰鸣而过又一辆兰博基尼呼啸而过我心里一万头草泥马奔腾MLGB心里暗想为神马开这车的人不是此刻看文章的你
走到半路了面试官给我打电话了说我怎么还没到说约定的是两点钟我一下子就懵逼了短信只有一个游客访问ID并没有通知我具体时间反正不管谁的疏忽我肯定是要迟到了于是我快马加鞭踩着贼难骑的共享单车背着微风一路狂奔到阿里园区已是汗流浃背油光满面气喘乎乎
面试迟到了印象肯定不好加上满头大汗的形象也不太好加上自己饥渴难耐这面是估计要GG了一进来就直奔主题这次是两个大Boss面试我
第一个面试官
1.先自我介绍一下说一下项目的技术栈以及项目中遇到的一些问题啥的
这个问题就是个开场白简要说明一下问题都不大这个面试官就是第一次打电话给我面试的那个boss所以技术那块boss心里也有个底细所以没再问技术问题
2.一个业务场景面对产品不断迭代以及需求的变动该怎么应对具体技术方案实现
具体业务场景我就不一一描述Boss在白板上画了一个大致的模块图然后做了一些需求描述
然后需求一层一层的改变然后往下挖主要是考察应对产品能力以及对代码的可维护性和可拓展性这些考察开放性问题我觉得还考察一些沟通交流方面的能力因为有些地方面试官故意说得很含糊反正就是一个综合能力以及对产品的理解中间谈到怎么实现也问到了一些具体的点记得问到的有一下几个
怎么获取一个元素到视图顶部的距离
getBoundingClientRect获取的top和offsetTop获取的top区别
③事件委托
第二个面试官
1.业务场景比如说百度的一个服务不想让阿里使用如果识别到是阿里的请求然后跳转到404或者拒绝服务之类的
主要是考察http协议头Referer然后怎么判断是阿里的ip或者啥的我也不太清楚
2.二分查找的时间复杂度怎么求是多少
排序的还算清楚一点查找真的不知所措没回答上来也没猜意义不大不会就是不会
3.XSS是什么攻击原理怎么预防
这个很简单跨站脚本攻击XSS(cross site scripting)攻击类型主要有两种反射型和存储型简单说了一下如何防御
①转义
②DOM解析白名单
③第三方库
④CSP
自己对web安全这块系统学习过前前后后大约了解了很多对于XSS,CSRF,点击劫持Cookie安全HTTP窃听篡改密码安全SQL注入社会工程学都有一定了解所以这个自然也不在话下
4.线性顺序存储结构和链式存储结构有什么区别以及优缺点
我是类比JS数组和对象来回答的反正还算凑合吧自己都数据结构这块多少还是有些印象所以入了前端对数据结构和算法确实一直淡忘了
5.分析一下移动端日历PC端日历以及桌面日历的一些不同和需要注意的地方
这个我能想到的大致都说了一遍不同的场景交互和细节以及功能都有所偏差以及功能的侧重都可能不同
6.白板写代码用最简洁的代码实现数组去重
我写了两种实现方式
ES6实现
[...new Set([1,2,3,1,'a',1,'a'])]
ES5实现
[1,2,3,1,'a',1,'a'].filter(function(ele,index,array){
return index===array.indexOf(ele)
})
7.怎么实现草稿多终端同步以及冲突问题
这个回答的不算好本来也想到类比git的处理方式但是说的时候往另外一个方面说了导致与面试官想要的结果不一样
最后说目前的工作经验达不到P6水平业务类稍弱阿里现在社招只要P6的高级工程师但是可以以第二梯队进去就是以第三方签署就业协议一年后可以转正就是俗称的外包多少还是有点遗憾面了四轮面了个外包最后放弃这份工作了
最后感谢boss一直以来的关照和器重
学习前端的同学们欢迎加入前端学习交流群
前端学习交流QQ群461593224

View File

@@ -0,0 +1,39 @@
## Class和普通构造函数有何区别
> 我们经常会用ES6中的Class来代替JS中的构造函数做开发
- Class 在语法上更加贴合面向对象的写法
- Class 实现继承更加易读易理解
- 更易于写 java 等后端语言的使用
- 本质还是语法糖使用 prototype

View File

@@ -0,0 +1,86 @@
## 前言
### ES6的主要内容
- 模块化的使用和编译环境
- Class与JS构造函数的区别
- Promise的用法
- ES6其他常用功能
本文来讲模块化的使用和编译环境
### 面试常见问题
- ES6 模块化如何使用开发环境如何打包
- Class 和普通构造函数有何区别
- Promise 的基本使用和原理
- 总结一下 ES6 其他常用功能
### ES6的现状
- 开发环境已经普及使用
- 浏览器环境却支持不好需要开发环境编译
- 内容很多重点了解常用语法
- 面试开发环境的使用 + 重点语法的掌握
## 模块化的基本语法
1util1.js
```javascript
export default var a = 100;
export function foo {
console.log('util1-foo');
}
```
`export default`命令用于指定模块的默认输出显然一个模块只能有一个默认输出
有了默认输出之后其他模块加载该模块时import命令可以为该匿名变量/函数**任意的名字**
上面的代码中默认输出是一个变量当然我们也可以换成**默认输出一个匿名函数**
```javascript
export default function() {
console.log('util1-function');
}
```
2util2.js
```javascript
export var myUtil2 = 'this is util2';
export function fn1() {
console.log('util2-fn1');
}
export function fn2() {
console.log('util2-fn2');
}
```
上方代码中我把一个变量和两个函数作为了导出
3index.js

View File

@@ -0,0 +1,361 @@
## JS 有哪些数据类型
- 基本数据类型string number bool undefined null
- 引用数据类型objectsymbol
另外object 包括数组函数正则日期等对象NaN属于number类型
注意数据类型里没有数组因为数组属于object一旦说数组函数正则日期NaN是数据类型直接0分
## Promise 怎么使用
then
```javascript
$.ajax(...).then(成功函数, 失败函数)
```
链式 then
```javascript
$.ajax(...).then(成功函数, 失败函数).then(成功函数2, 失败函数2)
```
如何自己生成 Promise 对象
```javascript
function xxx(){
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve() 或者 reject()
},3000)
})
}
xxx().then(...)
```
## ajax手写
```javascript
let xhr = new XMLHttpRequest();
xhr.open('POST', '/xxxx');
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText)
}
}
xhr.send('a=1&b=2');
```
## 闭包是什么
```javascript
function fn1() {
var a = 2
function fn2() {
a++
console.log(a)
}
return fn2;
}
var f = fn1(); //执行外部函数fn1返回的是内部函数fn2
f() // 3 //执行fn2
f() // 4 //再次执行fn2
console.log(a); // 会报错a is not defined
```
参考链接
- [JS 中的闭包是什么](https://zhuanlan.zhihu.com/p/22486908)
## 这段代码里的 this 是什么
1fn() 里面的 this 就是 window
2fn() strict modethis 就是 undefined
3a.b.c.fn() 里面的 this 就是 a.b.c
4new F() 里面的 this 就是新生成的实例
5() => console.log(this) 这个this指的是外面的 this
参考链接
- [this 的值到底是什么](https://zhuanlan.zhihu.com/p/23804247)
## 什么是立即执行函数作用是
立即执行函数
1声明一个匿名函数2马上调用这个匿名函数如下
```javascript
(function(a, b) {
var name; //声明一个局部变量
console.log("a = " + a);
console.log("b = " + b);
})(123, 456);
```
**作用**创建一个独立的作用域防止污染全局变量
因为我们只能通过函数的形式声明一个局部变量当有了ES6之后我们可以通过let来定义一个局部变量
```javascript
{
let name
}
```
上面这段代码就相当于立即执行函数有了let立即执行函数就毫无意义
参考链接
## ES6 新特性
## async/await 语法了解吗目的是什么
目的把异步代码写成同步代码的形式
我们知道promise是这样写的
```javascript
let promise = new Promise((resolve, reject) => {
//进来之后状态为pending
console.log('111'); //这一行代码是同步的
//开始执行异步操作这里开始写异步的代码比如ajax请求 or 开启定时器)
if (异步的ajax请求成功) {
console.log('333');
resolve();//如果请求成功了请写resolve()此时promise的状态会被自动修改为fulfilled
} else {
reject();//如果请求失败了请写reject()此时promise的状态会被自动修改为rejected
}
})
console.log('222');
//调用promise的then()
promise.then(() => {
//如果promise的状态为fulfilled则执行这里的代码
console.log('成功了');
}
, () => {
//如果promise的状态为rejected则执行这里的代码
console.log('失败了');
}
)
```
有了await之后可以直接替换掉then如下
```javascript
function returnPromise(){
return new Promise( function(resolve, reject){
setTimeout(()=>{
resolve('success')
},3000)
})
}
returnPromise().then((result)=>{
result === 'success'
})
var result = await returnPromise()
result === 'success'
```
## 如何实现深拷贝
### 方式一JSON 来深拷贝
```javascript
var a = {...};
var b = JSON.parse(JSON.stringify(a)); //先将对象转成json字符串然后再转成对象
```
缺点JSON 不支持函数引用undefinedRegExpDate
### 方式二递归拷贝
```javascript
function clone(object){
var object2
if(! (object instanceof Object) ){
return object
}else if(object instanceof Array){
object2 = []
}else if(object instanceof Function){
object2 = eval(object.toString())
}else if(object instanceof Object){
object2 = {}
}
你也可以把 Array Function Object 都当做 Object 来看待,参考 https://juejin.im/post/587dab348d6d810058d87a0a
for(let key in object){
object2[key] = clone(object[key])
}
return object2
}
```
## 如何实现数组去重
### 方式1计数排序的逻辑只能针对正整数
```javascript
var a = [4,2,5,6,3,4,5]
var hashTab = {}
for(let i=0; i<a.length;i++){
if(a[i] in hashTab){
// 什么也不做
}else{
hashTab[ a[i] ] = true
}
}
//hashTab: {4: true, 2: true, 5: true, 6:true, 3: true}
console.log(Object.keys(hashTab)) // ['4','2','5','6','3']
```
### 方式二set
```javascript
Array.from(new Set(a));
```
###方式三
## 如何用正则实现 string.trim()
```javascript
function trim(string) {
return string.replace(/^\s+|\s+$/g, '')
}
```
## JS 原型是什么
参考链接
- [什么是 JS 原型链](https://zhuanlan.zhihu.com/p/23090041)
## ES 6 中的 class 了解吗
参考链接
- <https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes>
## 如何实现继承
- 构造函数
- 原型链
- extends
```javascript
```
```javascript
```
```javascript
```
```javascript
```

View File

@@ -0,0 +1,61 @@
## 前言
基础知识
- ES 6常用语法class modulePromise等
- 原型高级应用结合 jQuery zepto 源码
- 异步全面讲解从原理到 jQuery 再到 Promise
框架原理
- 虚拟DOM存在价值如何使用diff算法
- MVVM vueMVVMvue响应式模板解析渲染
- 组件化 React组件化JSXvdomsetState
混合开发
- hybrid
- H5
- 前端客户端通讯
内容优势
- 面试官爱问源码实现
- 介绍常用框架实现原理
- 介绍hybrid原理和应用
## ES6
- 模块化的使用和编译环境
- Class与JS构造函数的区别
- Promise的用法
- ES6其他常用功能
## 异步
- 什么是单线程和异步有什么关系

View File

@@ -0,0 +1,94 @@
## 前言
MVVM的常见问题
- 如何理解MVVM
- 如何实现MVVM
- 是否解读过Vue的源码
题目
- 说一下使用 jQuery 和使用框架的区别
- 说一下对 MVVM 的理解
- vue 中如何实现响应式
- vue 中如何解析模板
- vue 的整个实现流程
## 说一下使用 jQuery 和使用框架的区别
## MVVM / Vue
## MVVM模式
- Model负责数据存储
- View负责页面展示
- View Model负责业务逻辑处理比如Ajax请求等对数据进行加工后交给视图展示
数据驱动视图只关心数据变化DOM操作被封装
### MVVM / Vue的三要素
- **响应式**vue 如何监听到 data 的每个属性变化
- **模板引擎**vue 的模板如何被解析指令如何处理
- **渲染**vue 的模板如何被渲染成 html 以及渲染过程
### 什么是虚拟 DOM
传统的web开发是利用 jQuery操作DOM这是非常耗资源的
我们可以在 JS 的内存里构建类似于DOM的对象去拼装数据拼装完整后把数据整体解析一次性插入到html里去这就形成了虚拟 DOM
Vue1.0没有虚拟DOMVue2.0改成了基于虚拟DOM
### 如何理解MVC
C指的是Controller控制器能够控制视图的变化也能控制数据的变化
单项通信一般情况下是view 发出命令给控制器控制器处理业务逻辑后控制 ModelModel再去改 view
## hybrid
### 使用场景
不是所有的场景都适合用 hybrid
- 使用原生应用体验要求极致变化不频繁如头条的首页
- 使用 hybrid体验要求高变化频繁如新闻详情页
- 使用H5体验无要求不常用比举报反馈等

View File

@@ -0,0 +1,65 @@
## HTTP 状态码知道哪些
301 302 的区别
- 301 永久重定向浏览器会记住有缓存
- 302 临时重定向无缓存
## HTTP 缓存怎么做
强缓存
- **`Expires`****`Cache-Control`**
协商缓存
- 第一对`Last-Modified``If-Modified-Since`
- 第二对`ETag``If-None-Match`
## Cookie 是什么Session 是什么
### Cookie
- HTTP响应通过 Set-Cookie 设置 Cookie
- 浏览器访问指定域名是必须带上 Cookie 作为 Request Header
- Cookie 一般用来记录用户信息
### Session
- Session 是服务器端的内存数据
- session 一般通过在 Cookie 里记录 SessionID 实现
- SessionID 一般是随机数
## LocalStorage Cookie 的区别是什么
- Cookie 会随请求被发到服务器上 LocalStorage 不会
- Cookie 大小一般4k以下LocalStorage 一般5Mb 左右
## GET POST 的区别是什么
GET和POST本质上就是TCP链接并无差别但是由于HTTP的规定和浏览器/服务器的限制导致他们在应用过程中体现出一些不同
需要注意的是web 中的 get/post 只是 http 中的 get/post 的子集http 中的 get post 只是单纯的名字上的区别get 请求的数据也可以放在 request body 只是浏览器没有实现它但是 get 并不只是在 web 中使用
参考链接
- <http://www.cnblogs.com/zichi/p/5229108.html>
- <https://zhuanlan.zhihu.com/p/22536382>

View File

@@ -0,0 +1,7 @@
## 前言
攻击的原理也许你能讲出来主要是想知道如何发现这个网站的漏洞毕竟大部分的网站都已经把用户输入的内容各种花式过滤了

View File

@@ -0,0 +1,6 @@
## 前端基础
### 闭包和作用域面试喜欢问

View File

@@ -0,0 +1,21 @@
## 征服JavaScript面试系列 | 众城翻译
- [征服 JavaScript 面试什么是闭包](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-closure)
- [征服 JavaScript 面试什么是函数组合](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-function-composition)
- [征服JavaScript面试系列类继承和原型继承的区别](http://www.zcfy.cc/article/master-the-javascript-interview-what-s-the-difference-between-class-amp-prototypal-inheritance-2185.html)
- [征服 JavaScript 面试什么是纯函数](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-pure-function-2186.html)
- [征服 JavaScript 面试: 什么是函数式编程](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-functional-programming-2221.html)
- [征服 JavaScript 面试: 什么是 Promise](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-promise)

View File

@@ -0,0 +1,4 @@
- [HTTP最强资料大全](https://github.com/semlinker/awesome-http)

View File

@@ -0,0 +1,16 @@
```
var arr = [1, 2, 3];
fun(arr);
console.log(arr);
function fun(a) {
a = [];
}
```
上方代码的打印结果是[1,2,3]

View File

@@ -0,0 +1,360 @@
## 变量提升
先说三句总结性的话
- let 创建过程被提升了但是初始化没有提升
- var 创建初始化都被提升了
- function 创建初始化赋值都被提升了
### 变量提升的规律
在进入一个执行上下文后先把 var function 声明的变量前置再去顺序执行代码
PS作用域分为全局作用域和函数作用域用var声明的变量只在自己所在的所用域有效
我们举例来看看下面的代码
**代码 1**
```javascript
console.log(fn);
var fn = 1;
function fn() {
}
console.log(fn);
```
相当于
```javascript
var fn = undefined;
function fn() {
}
console.log(fn);
fn = 1;
console.log(fn);
```
打印结果
![](http://img.smyhvae.com/20180321_1810.png)
**代码 2**
```javascript
console.log(i);
for (var i = 0; i < 3; i++) {
console.log(i)
}
```
相当于
```javascript
var i = undefined;
console.log(i);
for (i = 0; i < 3; i++) {
console.log(i);
}
```
打印结果
![](http://img.smyhvae.com/20180321_1817.png)
**代码 3**
```javascript
var a = 1;
function fn() {
a = 2;
console.log(a)
var a = 3;
console.log(a)
}
fn();
console.log(a);
```
相当于
```javascript
var a = undefined;
function fn() {
var a
a = 2
console.log(a)
a = 3
console.log(a)
};
a = 1;
fn();
console.log(a);
```
打印结果
![](http://img.smyhvae.com/20180321_1827.png)
参考链接<https://github.com/jirengu/javascript-tutorial>
### 声明时的重名问题
假设`a`被声明为变量紧接着`a`又被声明为函数原则是声明会被覆盖先来后到就近原则
PS
- 如果`a`已经有值再用 var 声明是无效的
- 如果`a`已经有值紧接着又被赋值**赋值会被覆盖**
举例1
```javascript
var fn; //fn被声明为变量
function fn() {// fn被声明为function就近原则
}
console.log(fn); //打印结果function fn(){}
```
举例2
```javascript
function fn() {} //fn被声明为function且此时fn已经被赋值这个值就是function的对象
var fn; //fn已经在上一行被声明且已经有值 再 var 无效,并不会重置为 undefined
console.log(fn) //打印结果function fn(){}
```
既然再var无效但是再function是有效的
```javascript
function fn() {} //fn被声明为function且此时fn已经有值这个值就是function的对象
function fn() { //此时fn被重复赋值会覆盖上一行的值
console.log('smyhvae');
}
console.log(fn)
```
打印结果
![](http://img.smyhvae.com/20180321_1845.png)
### 函数作用域中的变量提升两点提醒
**提醒1**
在函数作用域也有声明提前的特性
- 使用var关键字声明的变量是在函数作用域内有效而且会在函数中所有的代码执行之前被声明
- 函数声明也会在函数中所有的代码执行之前执行
因此在函数中没有var声明的变量都会成为**全局变量**而且并不会提前声明
举例1
```javascript
var a = 1;
function foo() {
console.log(a);
a = 2; // 此处的a相当于window.a
}
foo();
console.log(a); //打印结果是2
```
上方代码中foo()的打印结果是`1`如果去掉第一行代码打印结果是`Uncaught ReferenceError: a is not defined`
**提醒2**定义形参就相当于在函数作用域中声明了变量
```
function fun6(e) {
console.log(e);
}
fun6(); //打印结果为 undefined
fun6(123);//打印结果为123
```
### 其他题目
**20180321面试题**
```javascript
var a = 1;
if (a > 0) {
console.log(a);
var a = 2;
}
console.log(a);
```
打印结果
```
1
2
```
上方代码中不存在块级作用域的概念if语句中用var定义的变量让然是全局变量
顺便延伸一下用let定义的变量是在块级作用域内有效
```javascript
```
```javascript
```
```javascript
```
```javascript
```
```javascript
```

View File

@@ -0,0 +1,35 @@
## 面试题
### 20180321面试题
```javascript
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
setTimeout(function () {
console.log(3);
}, 0);
console.log(4);
```
### 20180321面试题
```javascript
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
```
打印结果333

View File

@@ -0,0 +1,213 @@
## 20180323
### 什么是闭包闭包有什么作用
### ES6的新特性有哪些
作用域函数扩展扩展运算符默认参数箭头函数异步promise模块化
### 追问const常量有什么作用确定不能修改吗修改之后会报错吗你有没有试过
当时我的答案是斩钉截铁地说不能改其实我说错了后来查了一下准确答案是
- 如果是值类型值不可变
- 如果是引用类型地址不可变
所以说虽然我不能修改引用类型的指向但是我可以修改引用类型里的属性值
参考链接<https://segmentfault.com/q/1010000012836140?sort=created>
### 追问const的原理是什么
面试官问如果你定义了const什么是常量是它的值还是引用比如说我定义了一个const 的array那我能往里面插入数据吗
### 箭头函数和匿名函数有什么区别吗
箭头函数和匿名函数有个明显的区别箭头函数内部的this是词法作用域由上下文确定
普通函数的this指向是动态作用域箭头函数的this指向是依据词法作用域
参考链接<https://zhuanlan.zhihu.com/p/25093389>
### 可以讲一下promise的状态吗
### 追问如果我写setTimeout0再写一个promise哪个先执行
我回答错了
正确答案是任务队列可以有多个promise的任务队列优先级更高具体答案还需要再仔细看看
### http有了解吗
- 可以讲一下它的握手过程吗
- http的缓存有了解吗
- get和post区别
### 做过CDN吗
答得不具体
百度百科的解释是其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节使内容传输的更快更稳定
### Vue相关
- vue的双向绑定怎么实现的我是说怎么实现
我当时是回答MVVM模式其实还需要答出Object.defineProperty( )的细节以及虚拟DOM
- Vue里还有什么呢
数据驱动组件化
### 事件绑定onClick和addEventListener的区别
### 说一下DOM里的事件冒泡
### 用Webpack做过哪些功能
### 追问ES6转成ES5改动代码发现页面自动刷新你说一下整个流程
问的是webpack 自动刷新的流程我没回答好
### 追问既然webpack可以用来配置服务器如果我要联调怎么办
启动了webpack就可以直接连接到后端吗
### 说一下跨域
### gzip压缩有了解吗
### 你做过什么项目说一下
我做过电商网站
追问遇到过什么问题吗
我遇到了性能的问题
追问那你说一下性能的问题
我就答出了性能相关的五大点
### node和express有了解吗
### 追问requireJS是异步的吗
是异步的
### Vue你是怎么用的是把所有的代码都写在一个页面里的吗
我是模块化写的
怎么分类
追问vuex的的作用
### 移动端的触摸事件了解吗
- touchstart touchmove touchend touchcanceltouchcancel当触点由于某些原因被中断时触发
- 模拟 swipe 事件记录两次 touchmove 的位置差如果后一次在前一次的右边说明向右滑了
### 移动端的浏览器和电脑浏览器的 touch事件有区别吗
我说我没了解过
追问移动端默认会有0.2秒的延迟
我后来查了一下
点击延迟是指移动端浏览器在 touchend click 之间存在 300ms 350ms 的延迟
为了判断用户是否是进行双击操作因为移动端双击是放大文字的手势操作
主要是从点击屏幕上的元素到触发元素的 click 事件移动浏览器会有大约 300 毫秒的等待时间这是因为浏览器想看看你是不是要进行双击double tap操作
解决方法
- 将click事件换成touch end事件
- FastClickFastClick的实现原理是在检测到touchend事件的时候会通过DOM自定义事件立即出发模拟一个click事件并把浏览器在300ms之后真正的click事件阻止掉
事件发生顺序在移动端手指点击一个元素会经过touchstart --> touchmove -> touchend --click
### 如何自定义事件
自定义事件的代码如下
```javascript
var myEvent = new Event('clickTest');
element.addEventListener('clickTest', function () {
console.log('smyhvae');
});
//元素注册事件
element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent不是写 事件名 clickTest
```
### 说一下状态码
### 手机端的web开发怎么和原生做交互
比如web网页想调用手机的拍照功能怎么做再比如怎么分享到朋友圈
### vue的生命周期有了解吗
create和mount有什么区别吗
什么时候执行update

View File

@@ -0,0 +1,21 @@
01.md
### CommonJSRequireJS(AMD) SeaJSCMD区别
### Webpack 打包
### WebSocket
### ES6
ES6 是应该的部分不算加分项

View File

@@ -0,0 +1,42 @@
### 2018-03-08
- [jawil | 一年经验初探阿里巴巴前端社招](https://github.com/jawil/blog/issues/22)
此博主的博客签名
20180308_1703.png
- [2017我遇到的前端面试题](https://blog.dunizb.com//2017/09/08/interview-questions-2017/)
作者整理的这些题目很多是来自面试跳槽的视频非常推荐
作者说性能优化和ES6是必问的
- [2018年web前端经典面试题及答案](https://www.cnblogs.com/wdlhao/p/8290436.html)
写得很长啊
### 2018-03-11
- [2017年BAT面试题大全集](http://www.bijishequ.com/detail/421600?p=)
- [bat前端面试内容记录](https://www.jianshu.com/p/d94d5290328c)
### 2018-03-18
- [笔记阿里网易滴滴共十次前端面试碰到的问题](https://zhoukekestar.github.io/notes/2017/06/07/interview-answers.html)
- [笔记补充阿里网易滴滴共十次前端面试碰到的问题](https://zhoukekestar.github.io/notes/2017/07/06/interview-answers.html)

View File

@@ -0,0 +1,56 @@
## 前言
vdom vue React **核心**先讲哪个都绕不开它
vdom 比较独立使用也比较简单
如果面试问到 vue React 和实现免不了问 vdom
- vdom 是什么为何会存在 vdom
- vdom 的如何应用核心 API 是什么
- 介绍一下 diff 算法
## 什么是 vdom
### 什么是 vdom
DOM操作是昂贵的
步骤一用JS对象模拟DOM树
步骤二比较两棵虚拟DOM树的差异
步骤三把差异应用到真正的DOM树上

View File

@@ -0,0 +1,63 @@
### 2018-01-25
- [有时在面试时我都替候选人着急候选人完全可以在面试前准备](https://www.cnblogs.com/JavaArchitect/p/8353578.html)
### 2018-01-26
- [转眼人到中年前端老程序员无法忘怀的一次百度电话面试](https://www.cnblogs.com/chyingp/p/a-telephone-interview-long-age.html)
八年前的面经咋记得这么清楚
### 2018-01-27
- [16年毕业的前端er在杭州求职ing](https://www.cnblogs.com/qianduantuanzhang/archive/2018/01/27/8365670.html)
### 2018-02-04
- [2018秋招前端总结](https://www.cnblogs.com/Mr-stockings/archive/2018/02/02/8407295.html)
### 2018-02-25
- [前端开发面试题(CSS)](http://www.bijishequ.com/detail/379621)
- [超过20家的前端面试题](https://www.jianshu.com/p/8b68f4df749e)
- [来聊聊前端工程师的面试套路](https://baijiahao.baidu.com/s?id=1570338146494165&wfr=spider&for=pc)
- [我的前端进阶之路面试题](https://www.cnblogs.com/libin-1/p/6864344.html)
这几个链接里讲到了 less听说面试爱问 less Sass的区别
### 2018-03-02
- [记录前端的面试日常(持续更新)](https://www.cnblogs.com/fangdongdemao/p/8492563.html)
### 2018-03-06
- [我遇到的前端面试题2017](https://segmentfault.com/a/1190000011091907)
里面有很多面试跳槽里的内容

View File

@@ -0,0 +1,70 @@
## 写简历的注意事项
- 最多可以写深入了解但不要写精通
## 遇到不知道的问题该怎么回答
- 这块儿我没了解过准备回去看一下
- 这块儿我没研究过您有没有好的资料我可以补充一下细节
- 写不出详细的代码但是知道思路
## 项目经历
- 面试要体现项目的设计思路方案设计等
## 模块化思维
1模块化设计的关键词**封装继承****通用**的模块**先抽象后具体**达到**复用**面试记住
比如**panel按钮轮播图**列表等等都可以提取为**抽象**的组件复用
2页面有哪几个模块
3每个模块分成不同的文件然后在index页面中import
## ES6新特性
- letconst
- 函数扩展参数默认值箭头函数扩展运算符`...`
- for of 循环
- map
- 模块化
## 薪资
面试官"你要求多少薪资?"
能给个范围吗

View File

@@ -0,0 +1,149 @@
## JavaScript
### 存储相关请描述以下cookielocalStoragesessionStorage的区别
> 在H5之前cookie一直都是本地存储的一个重要的方法直到后面的两个出现了 就开始用后面的两个做本地存储
**1cookie**
- 本身用于客户端和服务器端的通信
- 但是它有本地存储的功能于是就被借用
我们可以通过`document.cookie`获取和修改cookie获取到的其实就是一个字符串
cookie用于存储时的缺点
- 存储量太小只有4kb
- 所有http请求都带着会影响获取资源的效率
- api简单需要封装才能用`document.cookie = ...`
## HTML5
### HTML5新增了哪些内容或API使用过哪些
新元素
- `<section>``<footer>` `<header>`
新的api
- 网络存储: sessionStorage localStorage
参考链接
- [笔记阿里网易滴滴共十次前端面试碰到的问题](https://zhoukekestar.github.io/notes/2017/06/07/interview-answers.html)
## CSS
### 如何让一个div元素隐藏你能想到的方式有几种
-
## ES6
### for eachfor infor of的区别
- `foreach`用于遍历数组是数组的一个方法不支持 return
- `for in`获取对象里属性的键
- `for of`获取对象里属性的值
## 网络相关
### 浏览器输入url到显示内容有哪些过程
1浏览器解析url包括协议域名端口号资源路径参数查询
2DNS解析
3TCP握手
4HTTP请求
5服务器处理请求
6浏览器渲染DOM treeCSS rule treerender tree
7display
参考链接
- [笔记阿里网易滴滴共十次前端面试碰到的问题](https://zhoukekestar.github.io/notes/2017/06/07/interview-answers.html)
- [what-happens-when-zh_CN](https://github.com/skyline75489/what-happens-when-zh_CN)
- [码农翻身 | 小白科普从输入网址到最后浏览器呈现页面内容中间发生了什么](https://mp.weixin.qq.com/s/3_DZKSP492uq9RfQ3eW4_A)
- 从输入URL到页面加载发生了什么<https://segmentfault.com/a/1190000006879700>
## GitHub
- []面试题和答案<https://github.com/markyun/My-blog/tree/master/Front-end-Developer-Questions/Questions-and-Answers>
- 面试题和答案<https://github.com/qiu-deqing/FE-interview>
有个题是浏览器输入url有哪些过程
- [讲到了Cookie和session](https://github.com/WarpPrism/Blog/issues/5)
- 这个也很全<https://github.com/gnipbao/Front-end-Interview-questions>
- <https://github.com/giscafer/front-end-manual/issues/3>
## 按时间排列
### 2018-03-11
- web前端面试题汇总<https://www.jianshu.com/p/2f7eb1ad7174>
- 2017前端面试题及答案总结<https://yeaseonzhang.github.io/2017/09/17/2017%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98%E5%8F%8A%E7%AD%94%E6%A1%88%E6%80%BB%E7%BB%93/>
### 2018-03-12-今日头条面试题
- [ 今日头条一面笔试面试题完整](http://blog.csdn.net/github_35924246/article/details/75675901)