Skip to content
大纲

语言基础

HTML

文档类型

指定 !DOCTYPE 表明使用 H5 标准,浏览器将使用标准模式进行解析

文档解析类型包括

  • 标准模式
  • 怪异模式:兼容旧版本浏览器
  • 近标准模式:与标准模式基本一致,在少数场景下采用怪异模式渲染

标准模式与怪异模式的区别

  • 盒子模型
    • 标准模式:盒子大小表现为 box-sizing: content (注:这里只是便于理解差异)
    • 怪异模式:盒子大小表现为 box-sizing: border (注:这里只是便于理解差异)
  • 图片元素垂直对齐方式
    • 标准模式:图片 vertial-align 表现为 baseline
    • 怪异模式:图片 vertial-align 表现为 bottom
  • 内联元素尺寸
    • 标准模式:宽高设置无效
    • 怪异模式:宽高设置有效
  • 元素百分比高度
    • 标准模式:正常生效
    • 怪异模式:根据内容高度变化
  • 溢出处理
    • 标准模式:溢出内容不被裁剪,呈现在元素框外
    • 怪异模式:溢出内容不被裁剪,元素框自动调整大小

语义化优点

  • 开发友好:增加了可读性,便于开发和维护
  • 机器友好:利于 SEO,利于文本处理

H5 新特性

  • 新语义标签
  • 表单扩展
  • 本地存储
  • 地理定位
  • 离线应用
  • 音频视频
  • canvas/webGL
  • history
  • webscoket
  • requestAnimationFrame

src 与 href 的区别

  • src: 指向外部资源位置,将资源内容下载并应当到文档内,下载时会暂停其他资源的处理
  • href: 指向网络资源位置,建立当前元素与资源之间的连接,下载时不会停止对当前文档的处理

CSS

选择器

基础选择器

  • 通配选择器: *
  • 标签选择器: tag
  • ID 选择器: #id
  • 类选择器: .class
  • 属性选择器: [attr] [attr operator value flag]
    • 关系符号(operator)如下
      • =: attr 的值为 value
      • ~=: attr 为以空格为分隔的值列表,其中包含 value
      • |=: attr 的值为 value 或以 value- 作为前缀
      • ^=: attr 的值以 value 作为开头
      • $=: attr 的值以 value 作为结尾
      • *=: attr 的值包含 value
    • 修饰符(flag)如下(可选)
      • iI: 匹配属性值时忽略大小写

关系选择器

  • 相邻兄弟选择器: A + B,B 为紧邻 A 之后同层级且符合条件的单一元素
  • 通用兄弟选择器: A ~ B,B 为位于 A 之后同层级且符合条件的全部元素
  • 子选择器: >
  • 后代选择器: (空格)

伪类选择器(这里仅列举部分)

  • :active
  • :hover
  • :last-child
  • :last-of-type

伪元素选择器(这里仅列举部分)

  • ::before
  • ::after
  • ::first-line
  • ::first-letter

选择器优先级

!important > 内联 > ID 选择器 > 类选择器 > 标签选择器

注意:获取元素实际的样式需要使用 getComputedStyle

html
<style>
  #black {
    color: black;
  }
</style>
<div id="black" style="color: red;">black</div>
<script>
  const black = document.getElementById("black");
  console.log(black.style.color); // red
  console.log(getComputedStyle(black).color); // rgb(0, 0, 0)
</script>

选择器匹配顺序

选择器按照从右向左的顺序进行匹配
选择器的层级不宜过深,会降低效率

  • link 引入的样式权重高于 @import
  • 页面加载时,link 会同步加载,@import 会在页面加载完再加载

元素类型

根据元素是否具有可替换内容分为

  • 可替换元素
  • 非替换元素

可替换元素可以通过修改其某个属性改变其呈现内容

可替换元素的特性

  • 样式表现在 CSS 作用域之外
  • 有自身尺寸
  • 对特定属性有自身规范
  • 都是行内元素

可替换元素的尺寸通常受以下三类尺寸影响

  • 固有尺寸: 元素的默认尺寸,隐含了宽高比例,该尺寸无法被修改
  • HTML 尺寸: 通过 HTML 元素属性修改元素尺寸(非 style 属性)
  • CSS 尺寸: 通过 CSS 指定元素尺寸

优先级: CSS 尺寸 > HTML 尺寸 > 固有尺寸(宽高比例) > 固有尺寸(尺寸数值)

盒子模型

盒子尺寸

内联非替换元素的垂直方向 margin padding border 不加入高度计算,但会发生渲染

margin 和 padding 百分比值基于父级宽度计算

滚动内容底部留白使用 margin 代替 padding 可以兼容 IE 和火狐

外边距合并

块级元素,垂直方向(默认 writing-mode 下)上会出现外边距合并现象(正值合并取大值,负值合并取小值,正副合并取和值)

  • 兄弟元素:元素的下边距与相邻兄弟的上边距进行合并
  • 父子元素:父元素与首个或末尾子元素上下边距进行合并,满足以下任一条件即可消除该现象
    • 父元素设置为块状格式化上下文元素
    • 父元素设置 border-top/bottom
    • 父元素设置 padding-top/bottom
    • 父元素与首个或末尾子元素之间添加内联元素
    • 对于底部外边距合并,设置父元素高度(height, min-height, max-height) 也可消除
  • 空块级元素:元素自身上下边距进行合并,满足以下任一条件即可消除该现象
    • 设置 border-top/bottom
    • 设置 padding-top/bottom
    • 添加内联元素
    • 设置高度(height, min-height)

幽灵空白节点

HTML5 声明中,内联元素前会创建一个同行高的 0 宽内联盒子;可以使用 font-size: 0修正

pug
div
  span

BFC | IFC | FFC | GFC

BFC: 块级格式化上下文,内部元素与外部元素相互隔离,满足以下条件之一即可

  • 如何创建
    • 根元素
    • 浮动元素
    • 脱离文档流: position: fixed|absolute
    • 行内块级元素: inline-block、table-cell、table-caption
    • overflow 非 visible 的块级元素
    • 弹性元素
    • 网格元素
    • 多列容器
  • 解决问题
    • 浮动元素带来的高度塌陷(通常设置 overflow: auto|hidden)
    • 外边距合并

IFC: 行内格式化上下文

  • 如何创建
    • 内联元素
    • 文本元素
  • 表现特点
    • 忽略垂直方向 padding、margin
    • 尺寸根据内容决定
    • 块方向上对齐:vertical-align
    • 行内方向上对齐:text-align

隐藏元素的方式

  • 视觉上隐藏
    • opacity: 0
    • visibility: hidden
    • transform: scale(0, 0)
  • 文档中隐藏
    • display: none

定位

position

  • static
  • relative
  • absolute
  • fixed
  • stick: 粘性定位(类似于滚动吸顶的效果)

转换

transform 提供了元素 位移、缩放、旋转、倾斜、透视 等表现形式

在位移方面,transform: translateposition: absolute 的区别

  • translate 创建复合图层,交由 GPU 处理,若用作动画,其最小单位非 px,动画表现更好
  • absolute: 触发当前元素的回流,交由 CPU 处理,若用作动画,其最小单位为 px,性能开支更高

浮动

浮动的特点

  • 包裹性/自适应:未设置宽度的浮动元素宽度为内容宽度,且不超过父元素宽度
  • 块状化并格式化上下文:浮动元素 display 转换为 block 或 table
  • 破坏文档流
  • 无 margin 合并

清除浮动

  • 在浮动元素后添加空元素并设置 clear: both (left/right 本质上只有一种情况生效)
    • 作用于块级元素,让当前元素不受前一个 float 元素影响(不会改变 float 元素本身)
    • left/right 对应前一个 float 元素的浮动方向,使用 both 可以免去判断
  • 创建 BFC,给浮动元素容器添加 overflow: hidden|auto
  • 利用伪元素,给浮动元素后添加 ::after { content: ""; display: block; clear: both; }

布局

流式文档

  • 流动模型:在默认文档流中布局,元素会具有流动性按照顺序垂直延申分布
  • 浮动模型:元素在文档流中布局,但元素具有移动的浮动性,其他内联元素在其附近环绕
  • 层模型:元素脱离文档流进行布局,脱离的部分相当于新的文档流,层层叠加

布局类型:通过 display 指定 外在盒子(blockinline)表现 和 容器盒子(flowflow-rootflexgridtable) 布局

  • 流式布局:默认的布局方式
  • 弹性布局:给定内容呈现规则,用于响应式的处理内容呈现
  • 网格布局:给定网格呈现规则,一般用于高层级内容模块的展示划分
  • 表格布局:表格元素默认,且不应应用于其他元素

响应式支持

响应式即针对不同的使用场景采用不同的呈现方式,一般通过屏幕尺寸区分应用场景,常见的处理方式有

  • 媒体查询: 通过 @media screen 判断当前屏幕尺寸,采取不同的呈现方式
  • 固定宽度:将不同设备的屏幕尺寸视为一致,常用于 小程序 等以移动设备为主的场景
    • 百分比单位:使用 vwvh,一般很少使用
    • 指定设备宽度:如设置 <meta name="viewport" content="width=750px">,常用于 小程序
    • 黑屏处理:固定使用场景,超出该场景下的部分使用黑屏处理,常用于 h5 游戏
  • 相对尺寸:尺寸使用 rem 进行描述,根据屏幕尺寸动态修改 document.documentElement.style.fontSize 的尺寸 (项目中可以使用 pxtorem 统一处理 rem 转换)
  • 弹性描述:使用 网格布局和弹性布局 处理响应式表现(可结合媒体查询使用)

JS

内置类型

  • 基本类型:string number boolen null undefined symbol bigint
  • 引用类型:object function
  • 获取类型:Object.prototype.toString.call(arg)

说明:null 属于基本类型,但 typeof null === 'object'

类型转换

强制类型转换:使用数据类型对变量进行手动转换,如 Number('123')
隐式类型转换:在运算时对错误的数据类型变量进行转换,如 '1' + 1 === '11'
对象类型转换:在发生类型转换时会调用 valueOftoString 方法

  • 当调用 valueOf 返回值为对象时,会继续调用 toString() 方法
  • 使用强制类型转换 String 时会直接调用 toString() 方法
  • ES6 中可以覆写 [Symbol.toPrimitive] 替换 valueOftoString

注意:

  • valueOftoString 在基本类型变量中无效
  • if()! 在判断引用类型时不会发生类型转换
  • == 需注意以下特殊比较
    • null == 0 // false, 其中+null0
    • undefined == 0 // false,其中 +undefinedNaN
    • null == undefined // true
  • 字符串数字在进行 >/< 比较时是按位比较的
js
var obj = {
  valueOf() {
    console.log("调用 valueOf");
    return 233;
  },
  toString() {
    console.log("调用 toString");
    return 666; // 输出结果为 "666"
  },
  // NOTE: [Symbol.toPrimitive] 会覆盖 valueOf 和 toString
  // [Symbol.toPrimitive]() {
  //   return 2;
  // },
};
obj == 233; // 调用 valueOf true
String(obj); // 调用 toString "666"

// [] 调用 valueOf 返回 [],再调用 toString 返回 ""
// ![] 不触发类型转换,直接返回 false
[] == ![]; // true     相当于 "" == false
[1] == true; // true   相当于 1 == true
[2] == true; // false  相当于 2 == true => 2 == Number(true) => 2 == 1

undefined == false; // false 基本类型,直接比较不发生类型转换
null == false; // false   null 属于基本类型

变量提升

变量提升指先调用后声明的情况,js 代码在执行前会进行解析,functionvar 声明的变量会提升到执行上下文的头部

  • 在解析阶段,function 声明的函数存入内存,在执行阶段会跳过赋值
  • 在解析阶段,var 声明的变量会提升声明,需要在执行阶段才会赋值
  • 同一作用域中变量提升的优先级高于父级作用域
  • letconst 不会发生变量提升
js
console.log(a); // 输出 a 函数
a();
var a = "a";
console.log(a); // 'a'
function a() {
  console.log(a); // undefined
  var a = "a -> a";
}
a(); // error

闭包

闭包是一个函数和对其周围状态(词法环境)的引用的组合;
闭包可以让一个内层函数访问其外层函数的作用域
闭包最大的作用是隐藏变量,避免外部访问

js
for (var i = 1; i <= 5; i++) {
  setTimeout(
    function timer(i) {
      console.log(i);
    },
    i * 1000,
    i
  );
}

原型链

函数和类可以在其原型(prototype属性)上扩展方法和属性
在继承时,子类的 __proto__ 指向父类的原型,自身通过 prototype 扩展原型方法和属性
在实例化时,实例的 __proto__ 指向其类的 prototype
在调用方法时会按照先自身、后递归向上查询原型方法的顺序执行

ES5

js
function Klass(value) {
  this.value = value;
}
Klass.prototype.showValue = function () {
  console.log(this.value);
};
Klass.showValue = function () {
  console.log("static function");
};

ES6

js
class Klass {
  constructor(value) {
    this.value = value;
  }
  showName() {
    console.log(this.name);
  }
  static showName() {
    console.log("static function");
  }
}

ES5 中的实例可以使用 instance.constructor() 调用构造函数
ES6 中的实例不能使用 instance.constructor() 调用构造函数

继承

ES5 (借用上面的 Klass)

js
function Child(value, child) {
  Klass.call(this, value);
  this.child = child;
}
Child.__proto__ = Object.create(Klass.prototype);
Child.prototype.constructor = Child;
Child.prototype.showChild = function () {
  console.log(this.child);
};

ES6(借用上面的 Klass)

js
class Child extends Klass {
  constructor(value, child) {
    super(value);
    this.child = child;
  }
  showChild() {
    console.log(this.child);
  }
}

new 的过程

const ret = new Klass

  1. 创建空对象
  2. 赋值原型链 instance.__proto__ = Klass.prototype
  3. 调用构造函数
  4. 返回实例或构造函数返回值 return isObjOrFn(ret) ? ret : instance

instanceof 的过程

A instanceof B

  1. 获取对象的 __proto__
  2. 判断 __proto__ 是否等于 B.prototype
  3. 若不满足则向上遍历直到 __proto__null

this

在不改变 this 指向的情况下,this 拥有指向最后调用它的对象
若找不到该对象,则默认为全局对象

改变 this 指向

  • 箭头函数:箭头函数中 this 指向函数所在上下文中的 this
  • call/apply/bind

模块

CommonJS 模块

  • 基于函数实现
  • 引入时会执行一次
  • 再次引入会获取缓存

ES6 模块

  • 引入时会执行一次
  • 重复引用只执行一次
  • 输出内容可以为接口
  • 输出接口内容可以异步修改

重要区别

  • CommonJS 输出内容为值拷贝
  • ES6 输出内容为值引用