# 中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)
## 引言
当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖~🤣。缩减HC、裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀。但博主始终相信,**寒冬之中,人才更是尤为珍贵。只要有过硬的操作和装备,在逆风局下,同样也能来一波收割翻盘。**
博主也是年前经历了一番厮杀,最终拿到多家大厂的 offer。在闭关修炼的过程中,自己整理出了一套面试秘籍供自己反复研究,后来给了多位有需要的兄台,均表示相当靠谱,理应在这寒冬之中回报于社会。于是决定花点精力整理成文,让大家能比较系统的反复学习,快速提升自己。
面试固然有技巧,但绝不是伪造与吹流弊,通过一段短时间沉下心来闭关修炼,出山收割,步入大厂,薪资翻番,岂不爽哉?🤓
中篇已新鲜出炉,速速杀入
- [面试中篇](https://github.com/xd-tayde/blog/blob/master/interview-2.md);
- [面试下篇](https://github.com/xd-tayde/blog/blob/master/interview-3.md);
## 修炼原则
想必大家很厌烦笔试和考察知识点。因为其实在平时实战中,讲究的是开发效率,很少会去刻意记下一些细节和深挖知识点,脑海中都是一些分散的知识点,无法系统性地关联成网,一直处于似曾相识的状态。不知道多少人和博主一样,至今每次写阻止冒泡都需要谷歌一番如何拼写。🤪。
以如此的状态,定然是无法在面试的战场上纵横的。其实面试就犹如考试,大家回想下高考之前所做的事,无非就是 **理解** 和 **系统性关联记忆**。本秘籍的知识点较多,花点时间一个个理解并记忆后,自然也就融会贯通,无所畏惧。
由于本秘籍为了便于记忆,快速达到应试状态,类似于复习知识大纲。知识点会尽量的精简与提炼知识脉络,并不去展开深入细节,面面俱到。有兴趣或者有疑问的童鞋可以自行谷歌下对应知识点的详细内容。😋
## CSS
### 1. 盒模型
页面渲染时,dom 元素所采用的 **布局模型**。可通过`box-sizing`进行设置。根据计算宽高的区域可分为:
- `content-box` (W3C 标准盒模型)
- `border-box` (IE 盒模型)
- `padding-box`
- `margin-box` (浏览器未实现)
### 2. BFC
**块级格式化上下文**,是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。
> IE下为 Layout,可通过 zoom:1 触发
- 触发条件:
- 根元素
- `position: absolute/fixed`
- `display: inline-block / table`
- `float` 元素
- `ovevflow` !== `visible`
- 规则:
- 属于同一个 BFC 的两个相邻 Box 垂直排列
- 属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
- BFC 中子元素的 margin box 的左边, 与包含块 (BFC) border box的左边相接触 (子元素 absolute 除外)
- BFC 的区域不会与 float 的元素区域重叠
- 计算 BFC 的高度时,浮动子元素也参与计算
- 文字层不会被浮动层覆盖,环绕于周围
- 应用:
- 阻止`margin`重叠
- 可以包含浮动元素 —— 清除内部浮动(清除浮动的原理是两个`div`都位于同一个 BFC 区域之中)
- 自适应两栏布局
- 可以阻止元素被浮动元素覆盖
### 3.层叠上下文
元素提升为一个比较特殊的图层,在三维空间中 **(z轴)** 高出普通元素一等。
- 触发条件
- 根层叠上下文(`html`)
- `position`
- css3属性
- `flex`
- `transform`
- `opacity`
- `filter`
- `will-change`
- `-webkit-overflow-scrolling`
- 层叠等级:层叠上下文在z轴上的排序
- 在同一层叠上下文中,层叠等级才有意义
- `z-index`的优先级最高
### 4. 居中布局
- 水平居中
- 行内元素: `text-align: center`
- 块级元素: `margin: 0 auto`
- `absolute + transform`
- `flex + justify-content: center`
- 垂直居中
- `line-height: height`
- `absolute + transform`
- `flex + align-items: center`
- `table`
- 水平垂直居中
- `absolute + transform`
- `flex + justify-content + align-items`
### 5. 选择器优先级
- `!important` > 行内样式 > `#id` > `.class` > `tag` > * > 继承 > 默认
- 选择器 **从右往左** 解析
### 6.去除浮动影响,防止父级高度塌陷
- 通过增加尾元素清除浮动
- `:after /
: clear: both`
- 创建父级 BFC
- 父级设置高度
### 7.link 与 @import 的区别
- `link`功能较多,可以定义 RSS,定义 Rel 等作用,而`@import`只能用于加载 css
- 当解析到`link`时,页面会同步加载所引的 css,而`@import`所引用的 css 会等到页面加载完才被加载
- `@import`需要 IE5 以上才能使用
- `link`可以使用 js 动态引入,`@import`不行
### 8. CSS预处理器(Sass/Less/Postcss)
CSS预处理器的原理: 是将类 CSS 语言通过 **Webpack 编译** 转成浏览器可读的真正 CSS。在这层编译之上,便可以赋予 CSS 更多更强大的功能,常用功能:
- 嵌套
- 变量
- 循环语句
- 条件语句
- 自动前缀
- 单位转换
- mixin复用
面试中一般不会重点考察该点,一般介绍下自己在实战项目中的经验即可~
### 9.CSS动画
- `transition`: 过渡动画
- `transition-property`: 属性
- `transition-duration`: 间隔
- `transition-timing-function`: 曲线
- `transition-delay`: 延迟
- 常用钩子: `transitionend`
- `animation / keyframes`
- `animation-name`: 动画名称,对应`@keyframes`
- `animation-duration`: 间隔
- `animation-timing-function`: 曲线
- `animation-delay`: 延迟
- `animation-iteration-count`: 次数
- `infinite`: 循环动画
- `animation-direction`: 方向
- `alternate`: 反向播放
- `animation-fill-mode`: 静止模式
- `forwards`: 停止时,保留最后一帧
- `backwards`: 停止时,回到第一帧
- `both`: 同时运用 `forwards / backwards`
- 常用钩子: `animationend`
- 动画属性: 尽量使用动画属性进行动画,能拥有较好的性能表现
- `translate`
- `scale`
- `rotate`
- `skew`
- `opacity`
- `color`
### 经验
通常,CSS 并不是重点的考察领域,但这其实是由于现在国内业界对 CSS 的专注不够导致的,真正精通并专注于 CSS 的团队和人才并不多。因此如果能在 CSS 领域有自己的见解和经验,反而会为相当的加分和脱颖而出。
## JavaScript
### 1. 原型 / 构造函数 / 实例
- 原型`(prototype)`: 一个简单的对象,用于实现对象的 **属性继承**。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个`JavaScript`对象中都包含一个`__proto__` (非标准)的属性指向它爹(该对象的原型),可`obj.__proto__`进行访问。
- 构造函数: 可以通过`new`来 **新建一个对象** 的函数。
- 实例: 通过构造函数和`new`创建出来的对象,便是实例。 **实例通过`__proto__`指向原型,通过`constructor`指向构造函数**。
说了一大堆,大家可能有点懵逼,这里来举个栗子,以`Object`为例,我们常用的`Object`便是一个构造函数,因此我们可以通过它构建实例。
```js
// 实例
const instance = new Object()
```
则此时, **实例为`instance`**, **构造函数为`Object`**,我们知道,构造函数拥有一个`prototype`的属性指向原型,因此原型为:
```js
// 原型
const prototype = Object.prototype
```
这里我们可以来看出三者的关系:
```js
实例.__proto__ === 原型
原型.constructor === 构造函数
构造函数.prototype === 原型
// 这条线其实是是基于原型进行获取的,可以理解成一条基于原型的映射线
// 例如:
// const o = new Object()
// o.constructor === Object --> true
// o.__proto__ = null;
// o.constructor === Object --> false
实例.constructor === 构造函数
```
> 此处感谢 caihaihong 童鞋的指出。
放大来看,我画了张图供大家彻底理解:
### 2.原型链:
**原型链是由原型对象组成**,每个对象都有 `__proto__` 属性,指向了创建该对象的构造函数的原型,`__proto__` 将对象连接起来组成了原型链。是一个用来**实现继承和共享属性**的有限的对象链。
- **属性查找机制**: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象`Object.prototype`,如还是没找到,则输出`undefined`;
- **属性修改机制**: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: `b.prototype.x = 2`;但是这样会造成所有继承于该对象的实例的属性发生改变。
### 3. 执行上下文(EC)
执行上下文可以简单理解为一个对象:
- 它包含三个部分:
- 变量对象(VO)
- 作用域链(词法作用域)
- `this`指向
- 它的类型:
- 全局执行上下文
- 函数执行上下文
- `eval`执行上下文
- 代码执行过程:
- 创建 **全局上下文** (global EC)
- 全局执行上下文 (caller) 逐行 **自上而下** 执行。遇到函数时,**函数执行上下文** (callee) 被`push`到执行栈顶层
- 函数执行上下文被激活,成为 active EC, 开始执行函数中的代码,caller 被挂起
- 函数执行完后,callee 被`pop`移除出执行栈,控制权交还全局上下文 (caller),继续执行
### 2.变量对象
变量对象,是执行上下文中的一部分,可以抽象为一种 **数据作用域**,其实也可以理解为就是一个简单的对象,它存储着该执行上下文中的所有 **变量和函数声明(不包含函数表达式)**。
> 活动对象 (AO): 当变量对象所处的上下文为 active EC 时,称为活动对象。
### 3. 作用域
执行上下文中还包含作用域链。理解作用域之前,先介绍下作用域。作用域其实可理解为该上下文中声明的 **变量和声明的作用范围**。可分为 **块级作用域** 和 **函数作用域**
特性:
- **声明提前**: 一个声明在函数体内都是可见的, 函数优先于变量
- 非匿名自执行函数,函数变量为 **只读** 状态,无法修改
```js
let foo = function() { console.log(1) }
(function foo() {
foo = 10 // 由于foo在函数中只为可读,因此赋值无效
console.log(foo)
}())
// 结果打印: ƒ foo() { foo = 10 ; console.log(foo) }
```
### 4.作用域链
我们知道,我们可以在执行上下文中访问到父级甚至全局的变量,这便是作用域链的功劳。作用域链可以理解为一组对象列表,包含 **父级和自身的变量对象**,因此我们便能通过作用域链访问到父级里声明的变量或者函数。
- 由两部分组成:
- `[[scope]]`属性: 指向父级变量对象和作用域链,也就是包含了父级的`[[scope]]`和`AO`
- AO: 自身活动对象
如此 `[[scopr]]`包含`[[scope]]`,便自上而下形成一条 **链式作用域**。
### 5. 闭包
闭包属于一种特殊的作用域,称为 **静态作用域**。它的定义可以理解为: **父函数被销毁** 的情况下,返回出的子函数的`[[scope]]`中仍然保留着父级的单变量对象和作用域链,因此可以继续访问到父级的变量对象,这样的函数称为闭包。
- 闭包会产生一个很经典的问题:
- 多个子函数的`[[scope]]`都是同时指向父级,是完全共享的。因此当父级的变量对象被修改时,所有子函数都受到影响。
- 解决:
- 变量可以通过 **函数参数的形式** 传入,避免使用默认的`[[scope]]`向上查找
- 使用`setTimeout`包裹,通过第三个参数传入
- 使用 **块级作用域**,让变量成为自己上下文的属性,避免共享
### 6. script 引入方式:
- html 静态`