前端笔记--前端必备知识清单(持续更新)

文章旨在整理收集前端基础、计算机网络、浏览器、vue、react源码以及算法相关知识点。内容来自平时的阅读学习以及实践理解,由于内容量巨大,会进行持续的更新和补充。文章中涉及大量优秀博文的引用,大都在文末注明引用,如有遗漏或侵权,请联系作者处理。

版本 操作时间 操作说明
v_0.1.0 2019-4-16 20:57 初版
v_0.1.1 2019-4-17 13:20 正则表达式
v_0.1.2 2019-4-18 17:20 调整原型链相关表述
v_0.1.3 2019-4-18 21:11 跨域解决方案、设计模式、回流重绘
v_0.1.4 2019-4-21 15:02 修正事件循环表述、增加requestAnimationFrame理解
v_0.2.0 2019-4-21 17:17 Vue源码相关:nextTick原理解析
v_0.2.1 2019-4-24 11:33 Vue源码相关:v-on原理解析
v_0.2.2 2019-4-24 11:33 算法相关,排序与动态规划

一、HTML与CSS

1.css盒模型

  • w3c盒模型:content + padding + border + margin。元素宽高(css)等于content的宽高。
  • IE盒模型:元素的宽高(css)等于content + padding + border的宽度。

2.BFC块级格式化上下文

  • 形成条件:根元素;position: absolute/fixed; float;overflow:not visible;display: inline-block / table。
  • 应用:清除浮动

3.居中布局

  • 水平居中 行内元素:text-align: center;块级元素:margin:auto;
  • 垂直居中 line-height; absolute; flex;
  • 水平垂直居中 absolute;伪元素形成行内元素居中;flex + justify-content + align-items

4.清除浮动

设置父元素高度;形成bfc;伪元素clear: both;

5.flex常用api

引用:Flex 布局教程:语法篇
容器元素display: flex; 容器属性

flex-direction // 决定主轴的方向(即项目的排列方向)。
flex-wrap // 如果一条轴线排不下,如何换行。
flex-flow // 是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
justify-content // 定义了项目在主轴上的对齐方式。
align-items // 属性定义项目在交叉轴上如何对齐。
align-content // 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
复制代码

元素属性

order // 属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
flex-grow // 属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
flex-shrink // 属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
flex-basis // 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)
flex // flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
align-self // align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
复制代码

6.nodeType

  • 如果节点是元素节点,则 nodeType 属性将返回 1
  • 如果节点是属性节点,则 nodeType 属性将返回 2

二、JavaScript

1.原型与继承

原型:prototype

函数的对象属性,包含一个constructor属性,指向函数自身:Fun.prototype.constructor === Fun。

原型链

原型链由原型对象构成,是js对象继承的机制。每个对像都有[[prototype]]属性,主流浏览器以__proto__暴露给用户。__proto__指向对象的构造函数的原型属性(prototype)。 prototype的__proto__又指向**prototype对象(注意,这个prototype是一个对象结构)**的构造函数的原型;通过__proto__属性,形成一个引用链。在访问对象的属性时,如果对象本身不存在,就会沿着这条[[prototype]]链式结构一层层的访问。

构造函数

可以通过new来新建一个对象的函数。

原型与继承

函数拥有原型(prototype);而对象可以通过原型链关系([[prototype]])实现继承。函数是一种特殊对象,也拥有__proto__,即函数也会继承。函数的原型链是:函数静态方法—>原生函数类型的原型(拥有函数原生方法)—>原生对象原型(拥有对象原生方法) —> null
class A {}; class B extends A {};

类的继承

B.__proto__ = A.prototype; B.prototype.__proto__ = A.prototype;

new Fun操作符原理

  • Object.create(Fun.prototype);
  • 执行Fun,即类似类中的调用constructor()(为什么是执行constructor,因为constructor指向函数本身);
  • 如果constructor没有明确返回函数或对象,则返回第一步创建的对象。

2.函数执行相关

堆内存与栈内存

  1. 栈内存:由编译器自动分配与释放。我们可以直接操作栈内存中的值。js的基本类型存放在栈内存中,按值引用;
  2. 堆内存:链表结构的类型,可以动态分配大小,js引用类型占用内存空间的大小不固定,存储在堆内存中。由于JS不允许直接访问堆内存中的位置,因此我们不能直接操作js的引用类型。而是生成一个指针,并将它放到栈内存中,通过这个指针来操作引用类型。

垃圾回收

类型:标记引用(无法解决循环引用问题);标记清除(现在主流回收算法)。 标记清除算法的核型概念是:从根部(在JS中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的。那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。

内存泄漏

对于不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。 常见内存泄漏:

  1. 不合理的计时器(引用过时的外部变量)
  2. 被共享的闭包作用域(函数内部的函数共享一个闭包环境)
  3. 脱离dom引用(dom中元素被清除,但是变量还保持这对dom元素的引用)
  4. 意外的全局变量(未声明或者指向全局的this.xxx)

事件循环

事件循环是指: 执行一个宏任务,然后执行清空微任务列表,循环再执行宏任务,再清微任务列表。

异步任务分为宏任务(macrotask)与微任务 (microtask),不同的API注册的任务会依次进入自身对应的队列中,然后等待Event Loop将它们依次压入执行栈中执行。

- 微任务 microtask(jobs): promise / ajax / Object.observe(该方法已废弃)
- 宏任务 macrotask(task): setTimout / script / IO / UI Rendering

  • 产生宏任务队列的代码:script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)
  • 产生微任务的代码:Promise、MutaionObserver、process.nextTick(Node.js环境)

每次事件循环:

  1. 执行完主执行线程中的任务。
  2. 取出micro-task中任务执行直到清空。
  3. 取出macro-task中一个任务执行。
  4. 取出micro-task中任务执行直到清空。
  5. 重复3和4。

实例执行过程
  1. 执行完主执行线程中的任务(这里简单,没按执行顺序写)
    • 添加microtask队列[b, f, i];
    • 添加macrotask队列[a, c, j];
    • 输出in outer,in outer2;
  2. 执行microtask
    • 取出b -> 输出in promise;
    • 取出f -> 添加g到macrotask队列[a, c, j, g],添加h到microtask->[i, h]
    • 取出i,输出in promise2;
    • 取出g,输出in promise's promise,至此,microtask清空。
  3. 执行macrotask
    • 取出a,输出in timeout;
    • 取出c,[j,g].push(d), [].push(e) // 微任务队列;
    • 检测到微任务队列有子项e,取出执行,输出in time's promise;
    • 清空完微任务,继续执行宏任务队列,取出j,输出in timeout2;
    • 取出g,执行输出in promise's timeout;
    • 取出d,执行输出in timeout's timeout

requestAnimationFrame

requestAnimationFrame(cb)与setTimeout(cb, 0)同时注册时,可能在setTimeout之前执行,也可能在它之后执行。因为只有在一轮浏览器渲染结束时才回去调用raf。

执行环境及作用域

执行环境

执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境斗鱼一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
全局执行环境是最外围的执行环境,在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法被创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。(全局执行环境直到应用程序推出时才会被销毁)。

作用域链

当代码在一个环境中执行时,会创建变量对象的一个作用域链,保证对执行环境有权访问的所有变量和函数的有序访问。
作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象,其在最开始的时候只包含一个变量:arguments。作用域链的下一个变量来自包含环境,而️再下一个变量对象则来自下一个包含环境一直延续到全局执行环境。作用域链在创建的时候就会被生成,保存在内部的[[scope]]属性当中。其本质是一个指向变量对象的指针列表,它指引用但不实际包含变量对象。

[[scope]]

函数创建过程中,会创建一个预先包含外部活动对象的作用域链,并始终包含全局环境的变量对象。这个作用域链被保存在内部的[[scope]]属性中,当函数执行时,会通过复制该属性中的对象构建起执行环境的作用域链。

执行上下文

定义

执行上下文是指当前Javascript代码被解析和执行时所在环境的抽象概念,JavaScript 任何代码的运行都是在执行上下文中。

类型

  1. 全局执行上下文
  2. 函数执行上下文
  3. eval函数执行上下文

如何工作

执行上下文分为两个过程:

  1. 创建阶段
  2. 执行阶段
创建阶段

主要做了三件事

  1. this绑定(这解释了为什么this的值取决于函数的调用方式)
  2. 创建词法环境。(创建活动对象,变量和函数声明的位置标记(声明提升过程);根据[[scope]]创建作用域链)
  3. 创建变量环境(变量环境也是词法法环境,用于存储var声明的变量。)
执行阶段

变量赋值,语句执行等。

闭包

闭包是指有权访问另一个函数作用域中的变量的函数。其本质是函数的作用域链中保存着外部函数变量对象的引用。可以通过[[scope]]属性查看。因此,即使外部函数被销毁,但是由于外部环境中定义的变量在闭包的scope中还保持着引用,所以这些变量暂时不会被垃圾回收机制回收,因此依然可以在闭包函数中正常访问。**注意:同一个函数内部的闭包函数共享同一个外部闭包环境。**从下图可以看出,即使返回的闭包里面没有引用c,d变量,但是由于内部函数closure1中引用链,所以即使closure1未调用,闭包作用域中依然保存这些变量的引用。

3.js引用方式

  • html 静态

你可能感兴趣的:(前端笔记--前端必备知识清单(持续更新))