语言基础
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)如下(可选)
i或I: 匹配属性值时忽略大小写
- 关系符号(operator)如下
关系选择器
- 相邻兄弟选择器:
A + B,B 为紧邻 A 之后同层级且符合条件的单一元素 - 通用兄弟选择器:
A ~ B,B 为位于 A 之后同层级且符合条件的全部元素 - 子选择器:
> - 后代选择器:
␣(空格)
伪类选择器(这里仅列举部分)
:active:hover:last-child:last-of-type
伪元素选择器(这里仅列举部分)
::before::after::first-line::first-letter
选择器优先级
!important > 内联 > ID 选择器 > 类选择器 > 标签选择器
注意:获取元素实际的样式需要使用 getComputedStyle
<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
- 页面加载时,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修正
div
spanBFC | 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: 0visibility: hiddentransform: scale(0, 0)
- 文档中隐藏
display: none
定位
position
- static
- relative
- absolute
- fixed
- stick: 粘性定位(类似于滚动吸顶的效果)
转换
transform 提供了元素 位移、缩放、旋转、倾斜、透视 等表现形式
在位移方面,transform: translate 与 position: 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 指定 外在盒子(block、inline)表现 和 容器盒子(flow、flow-root、flex、grid、table) 布局
- 流式布局:默认的布局方式
- 弹性布局:给定内容呈现规则,用于响应式的处理内容呈现
- 网格布局:给定网格呈现规则,一般用于高层级内容模块的展示划分
- 表格布局:表格元素默认,且不应应用于其他元素
响应式支持
响应式即针对不同的使用场景采用不同的呈现方式,一般通过屏幕尺寸区分应用场景,常见的处理方式有
- 媒体查询: 通过
@media screen判断当前屏幕尺寸,采取不同的呈现方式 - 固定宽度:将不同设备的屏幕尺寸视为一致,常用于 小程序 等以移动设备为主的场景
- 百分比单位:使用
vw、vh,一般很少使用 - 指定设备宽度:如设置
<meta name="viewport" content="width=750px">,常用于 小程序 - 黑屏处理:固定使用场景,超出该场景下的部分使用黑屏处理,常用于 h5 游戏
- 百分比单位:使用
- 相对尺寸:尺寸使用
rem进行描述,根据屏幕尺寸动态修改document.documentElement.style.fontSize的尺寸 (项目中可以使用pxtorem统一处理rem转换) - 弹性描述:使用 网格布局和弹性布局 处理响应式表现(可结合媒体查询使用)
JS
内置类型
- 基本类型:
stringnumberboolennullundefinedsymbolbigint - 引用类型:
objectfunction - 获取类型:
Object.prototype.toString.call(arg)
说明:null 属于基本类型,但 typeof null === 'object'
类型转换
强制类型转换:使用数据类型对变量进行手动转换,如 Number('123')
隐式类型转换:在运算时对错误的数据类型变量进行转换,如 '1' + 1 === '11'
对象类型转换:在发生类型转换时会调用 valueOf 和 toString 方法
- 当调用
valueOf返回值为对象时,会继续调用toString()方法 - 使用强制类型转换
String时会直接调用toString()方法 - ES6 中可以覆写
[Symbol.toPrimitive]替换valueOf和toString
注意:
valueOf和toString在基本类型变量中无效if()和!在判断引用类型时不会发生类型转换==需注意以下特殊比较null == 0 // false, 其中+null为0undefined == 0 // false,其中+undefined为NaNnull == undefined // true
- 字符串数字在进行
>/<比较时是按位比较的
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 代码在执行前会进行解析,function 和 var 声明的变量会提升到执行上下文的头部
- 在解析阶段,
function声明的函数存入内存,在执行阶段会跳过赋值 - 在解析阶段,
var声明的变量会提升声明,需要在执行阶段才会赋值 - 同一作用域中变量提升的优先级高于父级作用域
let和const不会发生变量提升
console.log(a); // 输出 a 函数
a();
var a = "a";
console.log(a); // 'a'
function a() {
console.log(a); // undefined
var a = "a -> a";
}
a(); // error闭包
闭包是一个函数和对其周围状态(词法环境)的引用的组合;
闭包可以让一个内层函数访问其外层函数的作用域
闭包最大的作用是隐藏变量,避免外部访问
for (var i = 1; i <= 5; i++) {
setTimeout(
function timer(i) {
console.log(i);
},
i * 1000,
i
);
}原型链
函数和类可以在其原型(prototype属性)上扩展方法和属性
在继承时,子类的 __proto__ 指向父类的原型,自身通过 prototype 扩展原型方法和属性
在实例化时,实例的 __proto__ 指向其类的 prototype
在调用方法时会按照先自身、后递归向上查询原型方法的顺序执行
类
ES5
function Klass(value) {
this.value = value;
}
Klass.prototype.showValue = function () {
console.log(this.value);
};
Klass.showValue = function () {
console.log("static function");
};ES6
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)
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)
class Child extends Klass {
constructor(value, child) {
super(value);
this.child = child;
}
showChild() {
console.log(this.child);
}
}new 的过程
const ret = new Klass
- 创建空对象
- 赋值原型链
instance.__proto__ = Klass.prototype - 调用构造函数
- 返回实例或构造函数返回值
return isObjOrFn(ret) ? ret : instance
instanceof 的过程
A instanceof B
- 获取对象的
__proto__ - 判断
__proto__是否等于B.prototype - 若不满足则向上遍历直到
__proto__为null
this
在不改变 this 指向的情况下,this 拥有指向最后调用它的对象
若找不到该对象,则默认为全局对象
改变 this 指向
- 箭头函数:箭头函数中
this指向函数所在上下文中的this call/apply/bind
模块
CommonJS 模块
- 基于函数实现
- 引入时会执行一次
- 再次引入会获取缓存
ES6 模块
- 引入时会执行一次
- 重复引用只执行一次
- 输出内容可以为接口
- 输出接口内容可以异步修改
重要区别
- CommonJS 输出内容为值拷贝
- ES6 输出内容为值引用