【面试】前端面试八股文
温馨提示:这篇文章已超过367天没有更新,请注意相关的内容是否还可用!
| 前端思维导图 | 优点 |
|---|---|
| 大可爱html+css+js+node | 全面可下载 |
| 千峰html+css | 简洁漂亮 |
| 千峰js | 简洁漂亮 |
一、JS
1、使用
(1)标签引用
alert("Hello,World!");
(2)文件引用
2、特点
- 解释型语言:JS不需要被编译为机器码而是直接执行,开发轻松
- 动态型语言:JS变量与任何值类型都不关联,都可以重新分配类型值
- 弱类型语言:变量数据类型不确定,赋值后定义。当操作涉及不匹配的类型时,允许隐式转换
- 基于原型的面向对象
- 严格区分大小写
3、标识符
- 标识符:指给变量、函数、属性或函数参数起名字
- 要求:
- 第一个字符必须是字母、下划线( _ )或美元符号( $ )
- 其它字符可以是字母、下划线、美元符号或数字
- 按照惯例,ECMAScript 标识符采用驼峰命名法
- 标识符不能是关键字和保留字符
4、数据类型
(1)数据类型
- 简单/基本数据类型:在存储变量中存储值本身,因此也叫值类型,存放到栈(空间)
名称 类型 值 String 字符串型 ‘123’ Number 数值型 123 Boolean 布尔型 true/false Null null型 空 Undefined Undefined型 未定义 Symbol Symbol型 Symbol() 生成唯一值 Bigint 整数型 大整数 - 复杂数据类型:在存储变量中存储地址,因此也叫引用数据类型,存放到堆(空间)
- 通过new关键字创建的对象(系统对象、自定义对象)
名称 类型 值 Object 对象 { “key”:“value” } Array 数组 […] Function 函数 fn() Date 日期函数 new Date() Math 数学公式 Math RegExp 正则 new RegExp(“正则表达式”, “匹配模式”) (2)类型判断
- typeof obj:不适用复杂类型判断,多显示object
console.log(typeof "123") // string console.log(typeof 123) // number console.log(typeof true) // boolean console.log(typeof undefined) // undefined console.log(typeof null) // object => 所有值均32位,最低的3位表示数据类型,null全部为0,而object前三位是000
- obj instanceof Object :不适用基本类型判断
console.log([1, 2] instanceof Array) // true console.log(function(){} instanceof Function) // true console.log({a:1} instanceof Object) // true console.log(new Date() instanceof Date) // true console.log(new RegExp() instanceof RegExp) // true- obj.constructor:直接找到元素的构造函数类型
const str = '111' const num = 666 const sym = Symbol(66) const arr = [1,2,3,5] const date = new Date() const func = function(){} const reg = new RegExp() const map = new Map() const set = new Set() // null和undefined没有constructor,obj.constructor => Object() { [native code] } console.log(str.constructor === String) // true console.log(num.constructor === Number) // true console.log(sym.constructor === Symbol) // true console.log(arr.constructor === Array) // true console.log(date.constructor === Date) // true console.log(func.constructor === Function) // true console.log(reg.constructor === RegExp) // true console.log(map.constructor === Map) // true console.log(set.constructor === Set) // true- Object.prototype.toString.call(obj):最准确,推荐使用
Object.prototype.toString.call("") // "[object String]" Object.prototype.toString.call(123) // "[object Number]" Object.prototype.toString.call(true) // "[object Boolean]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(Symbol()) // "[object Symbol]" Object.prototype.toString.call(42n) // "[object BigInt]" Object.prototype.toString.call({ a: 1 }) // "[object Object]" Object.prototype.toString.call([1, 2]) // "[object Array]" Object.prototype.toString.call(new Date()) // "[object Date]" Object.prototype.toString.call(function () {}) // "[object Function]"(3)类型转换
- 类型转换:把数据类型的变量转换成需要的数据类型
- 显示转换:根据逻辑需要对数据进行显示转换
转换类型 方法 含义 String String(数据) 转换为字符串 变量.toString(进制) 转换为对应进制字符串 Number Number(数据) 转换为数字 parseInt(数据) 只保留整数 parseFloat(数据) 可以保留小数 Boolean Boolean(数据) 转换为布尔值 - 隐式转换:某些运算符被执行时,系统自动转换
+:一元操作符转换成Number;任何数据和字符串相加结果都是字符串
- * /:把数据转成数字类型
转换类型 原始数据类型 转换后的值 String 数字类型 'n' null 'null' undefined 'undefined' 布尔类型 true变'true',false变'false' Number 空字符/null 0 非空字符串 数字/NaN(有非数字) true/false 1/0 undefined NaN NaN typeof NaN => "number" Boolean String 非空字符串为true,空字符串为false Number 非零数字为true,0和NaN为false Object 任何对象为true,null为false Undefined 无true,Undefined为false 运行环境对数据类型隐式转换的影响:很多内置函数期望传入的参数数据类型是固定的,如:alert(value)期望传入string类型参数,如果传入number或object等非string类型的数据,就会发生数据类型的隐式转换
5、深浅拷贝
(1)基本类型拷贝
- 基本类型数据的值保存在栈中,对它进行拷贝时,为新变量开辟了新空间,数据互相不影响,不涉及深浅拷贝问题
(2)引用类型拷贝
- 复杂数据类型存储在栈中的值是一个指针,指向存储对象的内存地址,涉及深浅拷贝问题
- 浅拷贝:仅复制指向某对象的指针,不复制对象本身,新旧对象共享同一块内存
- 深拷贝:创造一个相同的对象,新旧对象不共享内存,修改新对象不会改到原对象
类型 与原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象 赋值 是 改变原数据 改变原数据 浅拷贝 否 不改变原数据 改变原数据 深拷贝 否 不改变原数据 不改变原数据 深拷贝方法
- JSON:JSON.stringify(),JSON.parse()
- Object.assign()
- jQuery 方法 $.extend()
- 递归
6、var let const
- 相同点:声明变量
- 不同点:
类型 var let const 作用域 函数作用域 块作用域 块作用域 重新赋值 是 是 否 声明不赋值 是 是 否 变量提升 是 否 否 重复声明 是 否 否 全局声明变量为window对象属性 是 否 否 尽量避免使用var,优先使用const,未来会修改的变量使用let
const必须初始化,声明时大写变量,不能修改变量声明的值,可以修改对象内部属性
let无需初始化,不可以修改变量声明的值
7、箭头函数
- 匿名:都是匿名函数,使用=>简化定义
- this:声明环境确定箭头函数this指向,通过查找作用域链确定this值,无法改变this指向
- new:不能作为构造函数使用,同样也没有new.target值和原型
- arguments:箭头函数没有自己的arguments对象,可以访问外围函数的arguments对象或用rest参数…解决
适合与this无关的回调 :定时器、数组回调
不适合与this有关的回调: 事件回调 、对象的方法
判断箭头函数
8、原型和原型链(面向对象编程)
- 面向对象编程是对程序的更高级别封装,高度复用
(1)构造函数
- 定义:使用new关键字来创建对象的函数,首字母一般大写
- 功能:存放全局变量
- 步骤
- 创建一个新对象
- 将构造函数的作用域赋给新对象(this指向实例对象)
- 执行构造函数中的代码(为实例对象添加属性)
- 返回新对象(实例对象)
function Person(name, age) { this.name = name; this.age = age; this.species = '人类'; this.say = function () { console.log("Hello"); } } let per1 = new Person('xiaoming', 20);(2)实例对象
- 定义:通过构造函数new出来的对象,所有函数都是Function()的实例
- 功能:存放数据
(3)原型对象
- 定义:构造函数创建的某个实例的原型对象
- 功能:存放对应数据的操作方法(事件处理函数)
- 显式原型:利用prototype属性查找原型,是函数类型数据的属性
- 隐式原型:利用__proto__属性查找原型,这个属性指向当前对象构造函数的原型对象,是对象类型数据的属性,可以在实例对象上使用
js每个函数类型数据,都有一个prototype属性指向原型对象
原型对象又有个constructor属性,指向它的构造函数
- 原型链:如果某对象在自己和原型对象上都没有查到属性,通过__proto__属性继续查找原型对象的原型对象,尽头是Object.prototype,未找到返回undefined
9、作用域和作用域链
(1)作用域
- 定义:规定变量和函数的可使用范围
- 局部作用域:函数中可以访问
- 全局作用域:全局中可以访问
(2)作用域链
- 定义:各作用域的嵌套关系,如果自身作用域未声明该变量,则通过作用域链层层查找
- 区别:类似原型链,但原型链中查找不到对象属性返回undefined;作用域链中查找不到属性抛出ReferenceError
- 作用域嵌套
- 内部作用域有权访问外部作用域
- 外部作用域无法访问内部作用域(闭包登场解决)
- 兄弟作用域不可互相访问
10、执行栈和执行上下文
(1)执行栈
- 特点是先进后出
- 当进入一个执行环境,就会创建出它的执行上下文,然后进行压栈;当程序执行完成时,它的执行上下文就会被销毁,进行弹栈
- 栈底永远是全局环境的执行上下文,栈顶永远是正在执行函数的执行上下文
- 只有浏览器关闭的时候全局执行上下文才会弹出
(2)执行上下文
- 全局执行上下文
- 创建一个全局的window对象,规定this指向window,执行js的时候压入栈底,关闭浏览器的时候弹出
- 函数执行上下文
- 每次函数调用时,都会新创建一个函数执行上下文
- 执行上下文分为创建阶段和执行阶段
- 创建阶段:函数环境会创建变量对象:arguments对象(并赋值)、函数声明(并赋值)、变量声明(不赋值),函数表达式声明(不赋值);确定this指向;确定作用域
- 执行阶段:变量赋值、函数表达式赋值,使变量对象编程活跃对象
- eval执行上下文
11、闭包
(1)定义
- 本质是函数嵌套函数
(2)作用
- 优点
- 保护:保护函数内的变量安全,避免命名冲突
- 保存:在内存中维持一个变量,可以做缓存不被垃圾回收机制回收
- 降耗:匿名自执行函数可以减少内存消耗
- 缺点
- 内存泄漏:被引用的私有变量不能被销毁,增大了内存消耗,可能导致内存泄漏;可以使用完变量后手动为它赋值null
- 降低性能:由于闭包涉及跨域访问,所以会导致性能损失;可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量减轻对执行速度的影响
(3)应用
- 设计模式中的单例模式
- for循环中的保留i的操作
- 防抖和节流
- 函数柯里化
12、内存泄露和垃圾回收机制
(1)内存泄漏
- 定义:不再用的内存没有被及时释放,导致该段内存无法被使用
- 原因:已经无法通过js访问某对象,而垃圾回收机制却认为该对象还在被引用,因此不释放该对象
- 影响:内存无法释放,积少成多,系统会越来越卡以至于崩溃
(2)垃圾回收机制
- 背景:写代码时创建的基本类型、对象、函数等,都需要占内存。JS基本数据类型存储在栈内存,引用数据类型存储在堆内存,但引用数据类型会在栈内存中存储一个实际对象的引用(内存泄漏)
- 定义:定期找出不可达的对象(变量设置为null),然后将其释放
- 方法:
- 标记清除法:分为标记和清除两个阶段,标记阶段需要从根节点遍历内存中的所有对象,并为可达的对象做上标记;清除阶段则把没有标记的对象(非可达对象)销毁
- 优点:实现简单
- 缺点:内存碎片化;内存分配速度慢
- 引用计数法:主要记录对象是否被其他对象引用,如果没有就被垃圾回收机制回收。策略是跟踪记录每个变量值被使用的次数,当变量值引用次数为0时,垃圾回收机制就会把它清理掉
- 优点:可以实现立即进行垃圾回收
- 缺点: 需要计数器;无法解决循环引用时计数不为0无法回收的问题
13、JS 执行机制
(1)进程和线程
- 进程:系统进行资源分配的最小单位,具有一定独立功能的程序关于某个数据集合上的一次运行活动
- 线程:系统安排CPU执行的最小单位,可以理解为子任务
- 关系:线程可以视作为进程的子集,一个进程可以有多个线程并发执行
- 区别:不同操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响;线程只是一个进程中的不同执行路径
(2)单线程
- 背景:JS有可视DOM,多线程可能会导致不同线程同时增、删、改DOM节点,导致浏览器无法顺利执行
- 定义:一次只能执行一段代码,执行时如果遇到耗时操作,默认停下等待操作完成后继续执行
- 解决:JS一般把比较耗时的操作做异步处理
(3)同步和异步
- 同步任务:在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行下一个任务
- 异步任务:进入任务队列的任务。只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程
- 事件循环:
- 同步任务依次进入主线程并执行,形成一个执行栈
- 异步任务进入任务队列并注册回调函数
- 所有同步任务执行完毕,从任务队列中提取异步任务执行
异步任务分为宏任务和微任务,任务队列也分为宏任务队列和微任务队列:
宏任务:运行环境提供的异步操作,如:setTimeOut、setInternal、DOM监听、UI rendering、ajax、事件绑定等
微任务:js 语言自身的异步操作,如:Promise的then、catch、finally和process的nextTick等
在一个宏任务周期中会执行当前周期所有微任务,都执行完毕进入下一个宏任务周期,所以任务执行顺序为:同步任务>微任务>宏任务
14、回调函数
(1)定义
- 函数也是一种变量,可以作为参数传给其他函数,在该外部函数中被调用以完成任务
(2)特点
- 执行:不会立即执行,通过()运算符调用才会执行
- 闭包:回调函数是一个闭包,能访问到其外层定义的变量
- this:指向离它最近或嵌套级别的函数的调用者
解决回调函数this指向的方法:
- 箭头函数
- let self = this
(3)优点
- 业务逻辑分离
- 避免重复代码
- 提高代码可维护性和可读性
(4)回调地狱
- 定义:回调函数中嵌套回调函数
- 目的:实现代码顺序执行
- 缺点:造成代码可读性差,后期不好维护
setTimeout(function () { console.log('第一次打印'); setTimeout(function () { console.log('第二次打印'); setTimeout(function () { console.log('第三次打印'); }, 1000) }, 2000) }, 3000)- 解决:Promise、async/await
15、Promise
(1)定义
- Promise是异步编程的一种解决方案,本质是一个构造函数
- Promise类似容器,保存着某个未来才会结束的事件(通常是一个异步操作)的结果
- 从语法上说,Promise是一个对象,从它可以获取异步操作的消息
- Promise提供统一的API,各种异步操作都可以用同样的方法进行处理
(2)特点
- 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的
(3)优缺点
- 优点:
- 可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
- Promise对象提供统一的接口,使得控制异步操作更加容易。
- 缺点:
- 无法取消Promise,一旦新建就立即执行,无法中途取消
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
- 当处于pending状态时,无法得知目前进展到哪一个阶段(刚开始或将完成)
(4)基本用法
- new Promise调用构造函数,其参数是一个函数,该函数的两个参数分别又是两个函数reslove和reject
- promise对象自带两个方法then和catch,这两个方法中会分别再传入一个回调函数,返回所需成功或失败的信息
- then方法返回的是一个新的Promise实例,因此可以采用链式写法,即then方法后面再调用另一个then方法
- catch方法调用指定发生错误时的回调函数
const promise = new Promise((resolve,reject)=>{ //异步代码 setTimeout(()=>{ // resolve(['111','222','333']) reject('error') },2000) }) promise.then((res)=>{ console.log('success',res) // success }).catch((err)=>{ console.log('fail',err) // error })-
- promise对象自带finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作,本质是then方法的特例
promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});- all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
const databasePromise = connectDatabase(); const booksPromise = databasePromise.then(findAllBooks); const userPromise = databasePromise.then(getCurrentUser); Promise.all([ booksPromise, userPromise ]) .then(([books, user]) => pickTopRecommendations(books, user))
16、async/await
- async/await 是对 Promise 的升级,用同步的方法写异步的代码
- async用于声明一个函数是异步的,await是等待一个异步方法执行完成
(1)async
- 作为一个关键字放到声明函数前面,表示该函数为异步任务,不会阻塞后面函数的执行
- 返回数据时自动封装为一个Promise对象
(2)await
- 不能单独使用,只能在使用async定义的函数中使用
- 后面可以直接跟一个 Promise实例对象
- 可以直接拿到Promise中resolve中的数据
17、改变this指向(call、apply、bind)
(1)this
- 普通函数:this指向调用者
- 箭头函数:本身无this,使用父作用域的this
普通函数:没有调用者,this默认指向window
箭头函数:this指向外包裹函数;如果没有外包裹函数,this指向window
特殊情况:严格模式下,this指向window就变为undefined
(2)改变this指向的三个方法
- fn.call(this指向对象, 参数列表)
let obj1 = { name : 'james', getName1 : function(a,b,c) { console.log(`getName ${this.name}`); // getName davis console.log(`参数:${a},${b},${c}`); // 参数:1,2,3 } } let obj2 = { name : 'davis', getName2 : function() { console.log(`getName ${this.name}`); } } obj1.getName1.call(obj2) obj1.getName1.call(obj2,1,2,3)call 在函数调用时改变函数this指向,第一个参数临时改变this指向并立即执行
call 支持传入多个参数
- fn.apply(this指向对象, 参数数组)
let obj1 = { name : 'james', getName1 : function(a,b,c) { console.log(`getName ${this.name}`); // getName davis console.log(`参数:${a},${b},${c}`); // 参数:1,2,3 } } let obj2 = { name : 'davis', getName2 : function() { console.log(`getName ${this.name}`); } } obj1.getName1.apply(obj2,[1,2,3])apply 在函数调用时改变函数this指向,第一个参数临时改变this指向并立即执行
apply 支持传入两个参数,第二个参数只能是数组形式
高级用法:Math.min/max.apply(false, arr)
- fn.bind(this指向对象, 参数列表)
let obj1 = { name : 'james', getName1 : function(a,b,c) { console.log(`getName ${this.name}`); // getName davis console.log(`参数:${a},${b},${c}`); // 参数:1,2,3 } } let obj2 = { name : 'davis', getName2 : function() { console.log(`getName ${this.name}`); } } let fn = obj1.getName1.bind(obj2,1,2,3) fn()bind 第一个参数改变this指向,不自动执行,调用返回函数永久改变this指向
bind 可以传入多个固定参数
18、继承
(1)背景
- 在实际编码过程中,很多类似方法存放于构造函数中,会导致内存浪费(内存泄漏),此时可以用继承解决
(2)定义
- 继承就是通过某种方式让一个对象可以访问另一个对象中的属性和方法
(3)方式
- 原型链继承:将父类的实例作为子类的原型
- 构造继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
- 实例继承:为父类实例添加新特性,作为子类实例返回
- 组合继承:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
- 寄生组合继承:通过寄生方式,砍掉父类的实例属性,这样在调用两次父类的构造的时,不会初始化两次实例方法/属性,避免组合继承的缺点
19、防抖和节流
(1)防抖
- 防抖:触发事件后n秒内只执行一次函数,若在n秒内重复触发,则重新计时
- 作用:防止抖动,避免事件重复触发
- 案例:输入框搜索联想、页面缩放
function debounce(fn, delay){ let timer = null; return function(){ clearTimeout(timer); timer = setTimeout(()=> { fn.apply(this, arguments); }, delay) } }(2)节流
- 节流:连续触发事件但n秒内只执行一次函数,稀释函数的执行频率
- 作用:减少流量,稀释事件触发频率
- 案例:鼠标频繁点击、鼠标滚动事件
function throttle(fn, delay){ let canUse = true return function(){ if(canUse){ fn.apply(this, arguments) canUse = false setTimeout(()=>canUse = true, delay) } } }20、BOM/DOM
(1)常用的 BOM 对象和方法
BOM 对象和方法 含义 alert(“提示”) 提示信息 confirm(“确认”) 确认信息 prompt(“输入”) 弹出输入框 open(“url”,“black/self”,“新窗口大小”) 打开网页 close() 关闭当前网页 (2)常见的 DOM 元素选择方式
DOM 元素选择方式 含义 getElementById 通过ID获取 getElementsByClassName 通过类名获取 getElementsByTagName 通过标签名获取 document.documentElement 获取 html document.body 获取 body querySelector 通过选择器获取一个元素(开发常用) querySelectorAll 通过选择器获取一组元素(开发常用) 二、HTML/CSS
1、标签
(1)块级元素(display:block)
- 块级元素独占一行
- 宽度默认是容器的 100%
- 宽、高,内、外边距都可以单独设置
- 可以容纳内联元素和其他块级元素
div 、p、h1~h6、hr
表单:form、fieldset、legend
列表:ul、ol、li、dl、dt、dd
表格:table、caption、thead、tbody、tfoot、th、tr、td
语义化标签:header、footer、main、nav、section、article、pre
(2)行内元素(display:inline)
- 和相邻的行内元素在一行
- 默认的宽度就是本身内容的宽度
- 宽、高无效,但是水平方向上的内外边距可以设置,垂直方向无效
- 行内元素只能容纳纯文本或其他行内元素(a 标签除外)
a、span、abbr、small、b、strong、em、br、cite、i、code、label、q、select、sub、sup、textarea、var
(3)行内块元素(display:inline-block)
- 和相邻的行内(块)元素在一行,中间有空白间隙
- 默认的宽度就是本身内容的宽度
- 宽、高,内、外边距都可以设置
- 通过 inline-block、浮动、绝对定位、固定定位转化过来
img、input
标签类型 排列方式 宽高边距设置 默认宽度 块级元素 独占一行 均可单独设置 容器的100% 行内元素 与相邻行内元素在一行 宽、高无效,
水平方向上的内外边距可以设置,垂直方向无效自身内容的宽度 行内块元素 与相邻的行内(块)元素在一行,
中间有空白间隙均可单独设置 自身内容的宽度 2、盒模型
名称 含义 width 宽度 height 高度 padding 元素内容与元素边框距离(填充) margin 元素边框间距(盒子间距) - 外边距合并:标准文档流中,块级元素 margin 在垂直方向出现叠加现象,大值覆盖小值
- 兄弟盒子:相邻块级元素垂直外边距取大值
只给同级元素中的一个元素设置 margin-top/bottom
给每一个元素添加父元素,然后触发 BFC 规则(不推荐)
- 父子盒子:嵌套块级元素垂直外边距子带父
使用伪元素 ::before,::after
触发 BFC (overflow、float、display、position)
给父元素设置 margin、padding (不推荐)
(1)标准盒模型(content-box)
- 设置的 width 与 height 只包括内容的宽、高, 不含边框和内外边距
- 尺寸计算公式:
盒子实际宽度 = border _ 2 + padding _ 2 + 内容宽度(width)
盒子实际高度 = border _ 2 + padding _ 2 + 内容高度(height)
(2)怪异盒模型(border-box)
- 设置的 width 与 height 包括内容的宽、高、边框、内边距,不含外边距
- 尺寸计算公式:
盒子实际宽度 = width = border _ 2 + padding _ 2 + 内容宽度
盒子实际高度 = height = border _ 2 + padding _ 2 + 内容高度
3、浮动与清浮动
(1)浮动
- 元素 float 脱离文档流移动(left/right),直到外边缘碰到包含框或另一个浮动框位置
(2)清浮动
- 清除浮动元素导致的高度塌陷,使页面布局正常显示
(1)添加高度:父元素添加 height/border/padding
(2)额外标签:浮动元素后添加一个空块级元素含属性 clear:both
(3)单伪元素:父元素添加 .clearfix::after{content:‘’; display:block;clear:both}
(4)双伪元素:父元素添加 .clearfix::after,.clearfix::before // 顺便清除外边距塌陷
(5)overflow :父元素添加 overflow:hidden
- 常用清浮动配置
.clearfix::after{ content: ''; display: block; height: 0; clear: both; visibility: hidden; }4、选择器
(1)基本选择器
基本选择器 使用 通配符 统一调配所有属性,用*调用 class 元素中定义 class 属性,用 .类名调用 id 元素中定义id属性,用 #id名调用 element 用 标签名调用 群组 同时选择 多个类名,逗号隔开 (2)层次选择器
层次选择器 使用 包含/后代 元素被包含在前一个元素内,选择此父元素内所有后代,用 父元素 后代元素 调用 子 匹配元素的孩子,用 父元素 > 子元素 调用 相邻兄弟 修改兄元素后第一个紧邻的弟元素样式,用 兄元素 + 弟元素 调用 通用兄弟 修改兄元素后所有弟元素样式,用 兄元素 ~ 弟元素 调用 (3)伪类选择器
- 链接伪类
链接伪类 含义 a:link 未访问 a:visited 访问后 a:hover 悬停时 a:avtive 点击时 - 目标伪类
- URL 通过锚点 #id 指向页面特定元素
- 用 :target 调用
目标伪类 含义 href="#id">操作者 事件触发对象 指向者
事件实施对象 E:target 查找点击操作者 - UI元素状态伪类
UI元素状态伪类 含义 E:hover 鼠标指针移到元素上 E:active 元素激活时 input:focus 表单元素获取焦点时 input:enabled 所有启用的表单元素 input:disabled 所有禁用的表单元素 input:checked 复选或单选按钮选中状态的表单元素 - 结构伪类
结构伪类 含义 E:first-child 查找兄弟元素中的第一个元素 E:last-child 查找兄弟元素中的最后一个元素 E:nth-child(n) 查找兄弟元素中的第n个元素 E:nth-last-child(n) 查找兄弟元素中倒数第n个元素 E:first-of-type 查找同类型兄弟元素中的第一个元素 E:last-of-type 查找同类型兄弟元素中的最后一个元素 E:nth-of-type(n) 查找同类型兄弟元素中第n个元素 E:nth-last-of-type(n) 查找同类型兄弟元素中倒数第n个元素 E:only-child 查找只有一个子元素的元素 E:only-of-type 查找只有一个同类型子元素的元素 E:empty 查找元素内部无任何文本和标签的元素 E:root 查找 HTML 页面中的根元素(html) E:first-letter 查找元素首字母 E:first-line 查找元素首行 E:selection 查找选中文本(修改字体/背景颜色) - 否定伪类
否定伪类 含义 E:not(F) E元素中除了F以外的所有元素 (4)伪元素
伪元素 含义 E::after content 在元素之后显示 E::before content 在元素之前显示 E::first-letter 定义指定元素首字母 E::first-line 定义指定元素首行 E::selection 定义被用户选取的部分(修改字体/背景颜色) (5)属性值匹配
- 属性值前面添加元素(E)进一步限制,不添加元素(E)选择范围更广
属性值 含义 E[attr] 包含指定属性的元素 [attr = “val”] 包含完全匹配属性值的元素 [attr ^ = val] 包含 val 片段开头的元素 [attr $ = val] 包含val 片段结尾的元素 [attr * = val] 包含 val 片段的元素 [attr ~ = val] 包含属性值字符的元素,val 单独存在或与其他属性值空格隔开 [attr | = val] 包含起始片段完全匹配的元素,起始值是 val 或 val- 开头 5、css 优先级
选择器 优先级 important! 无条件优先 内联样式 1000 id选择器 100 class、伪类、属性 10 标签伪元素 1 6、常见布局方式
常见布局
(1)float
- 特点:元素脱离了文档流,使父容器的高度塌陷,但是不脱离文本流
float 含义 none 默认无浮动 left 左浮动 right 右浮动 - 解决:清浮动
- 父级添加 overflow : hidden
- 父级添加 clearfix(推荐)
// 给父级元素添加了一个 ::after 伪元素,通过清除伪元素的浮动,达到撑起父元素高度的目的 .clearfix::after{ content: ''; display: block; height: 0; clear: both; visibility: hidden; }-
- 浮动元素后添加空标签(不推荐)
// 易造成结构混乱,不利于后期维护
(2)position
- 特点:可以精准定位页面中的任意元素
- 设置非 static 定位以后,可以设置 left、right、top、bottom
position 类型 是否脱标 参照系 是否常用 static 静态定位 否 标准流 很少 relative 相对定位 否 (占位) 自身位置 单独使用 absolute 绝对定位 是(不占位) 带定位的父级 搭配父级定位元素 fixed 固定定位 是(不占位) 浏览器可视区 单独使用 sticky 粘性定位 否 (占位) 浏览器可视区 单独使用 网页布局总结:
层级:标准流(海底) ==> 浮动盒子(陆地) ==> 定位盒子(天空)
区别:
① 标准流:块盒子上下排列
② 浮动:块盒子左右排列
③ 定位:盒子堆叠,默认后来居上,z-index 值调整堆叠顺序
(3)flex
- 决定大盒子(display:flex)中的小盒子如何分布、排列,创建自适应浏览器窗口的弹性布局
- 自动将行内子元素转换为块级子元素
- flex 属性
flex盒子属性 含义 flex-direction 主轴方向 flex-wrap 换行 flex-flow 前两条简写形式 justify-content 主轴对齐方式 align-items 侧轴对齐方式 align-content 多根轴线对齐方式 -
- 主轴对齐
justify-content 含义 flex-start 当前行的最左边 flex-end 当前行的最右边 center 当前行的中间位置 space-between 两端对齐(距离均分,首尾贴边) space-around 两端环绕(距离均分,首尾一半) space-evenly 两端均分(距离均分,首尾同均) -
- 侧轴对齐
align-items 含义 flex-start 当前行的最上边 flex-end 当前行的最下边 center 当前行的中间位置 stretch 子元素无高度或 auto,默认拉伸 baseline 以子元素第一行文字的基线对齐 - 项目属性
项目盒子 含义 order 项目的排列顺序,数值越小排列越靠前,默认为0 flex-grow 项目的放大比例,默认为0 flex-shrink 项目的缩小比例,默认为1 flex-basis 主轴是否有多余空间 flex 前三者简写,默认为0 1 auto align-self 单个项目个性对齐方式 (4)grid
- 特点:目前唯一一种 CSS 二维布局
- 网格单元:小格子,网格元素中最小的单位
- 网格线:划分网格的线,定义的是网格轨道
代码 类型 含义 display:grid/inline-grid 创建网格容器 使其直系子元素成为网格项目 grid-template-columns 设置列 设置列宽和数量(repeat()) grid-template-rows 设置行 设置行高和数量(repeat()) grid-gap 设置行间距和列间距 grid-row-gap与grid-column-gap的简写 place-items 设置项目位置 align-items和justify-items的简写 place-content 设置grid位置 align-content和justify-content的简写 (5)多列布局
功能 代码 含义 划分列数 column-count 值的大小代表列数多少 调整列宽 column-width 列宽过小无影响,列宽过大改变列数 调整间距 column-gap 一般不调整,默认即可 列间隔线 column-rule 类似border 检索列高 column-fill 检索列高是否均分,或占满父元素高度 balance(默认)/auto(自动撑满) 跨列标题 column-span 子元素设置all即可(前五全部设置父元素) (6)table
父级容器 - display:table
子级容器 - display:table-cell
(7)BFC
- 定义:BFC(Block Formatting Context),块级格式化上下文
- 特点:独立的布局空间,内部子元素不影响外部标签
触发条件 触发值 根元素 html float left、right、inherit position absolute、fixed overflow hidden、auto、scroll display flex、inline-flex、grid、inline-block、table-cell - 用途:
- 自适应两栏布局
- 清除内部浮动
- 阻止元素被浮动覆盖
- 阻止 margin 重叠
- 解决高度塌陷问题
高度塌陷:父元素自适应高度,子元素浮动后脱标(脱离标准流),父元素高度为 0
7、度量单位
- 布局视口:编写的页面
- 视觉视口:屏幕窗口
- 理想视口:通过meta标签将布局直接放到视觉视口
度量单位 含义 参照物 px 像素 / % 百分比 父元素 em 相对于父元素字体大小 父元素字体 rem 相对根元素字体大小 根元素字体 vw 相对于视口的宽度,1vw 等于视口宽度的1%(总视口宽度为100vw) 视口宽度 vh 相对于视口的高度,1vh 等于视口高度的1%(总视口高度为100vh) 视口高度 rpx 小程序独有,把所有设备的屏幕,在宽度上等分为750份 750rpx 8、HTML5/CSS3 新特性
(1)语义化标签
- 代码结构:使页面没有css的情况下,也能够呈现出很好的内容结构
- 有利于SEO:爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
- 提升用户体验:例如title、alt可以用于解释名称或者解释图片信息,以及label标签的灵活运用
- 便于团队开发和维护:语义化使得代码更具有可读性,让其他开发人员更加理解你的html结构,减少差异化
- 方便其他设备解析:如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页
(2)增强型表单
- 增加 type 类型:color、date、datetime、datetime-local、email、month、number、range、search、tel、time 等
- 增加 select 元素(下拉选框)、textarea 元素(文本域)、button 元素(按钮)、datalist 元素(预定义选项列表)
(3)媒体元素
- audio:音频
- video:视频
(4)canvas 绘图
- canvas 是画布,可以绘制复杂图形、做动画、处理图像、开发游戏、处理视频,支持二维矢量绘图、三维绘图
- canvas 元素本身没有绘图能力,绘制工作通过 JS 调用 getContext(‘2d’)完成
(5)svg 绘图(可伸缩矢量图)
(6)地理定位
- 使用 getCurrentPosition() 方法来获取用户的位置,从而实现队地理位置的定位
(7)拖放API
(8)Web Worker
- worker 加载脚本文件 => 创建独立工作线程(主线程之外运行) => worker 线程运行结束把结果返回给主线程(处理计算密集型任务,优化主线程) =>浏览器提供JS多线程运行的宿主环境
(9)Web Storage
- 掌握 cookie、Localstorage、 SessionStorage 三者区别
Web Storage 数据生命周期 存放数据大小 与服务器端通信 易用性 Cookie 可设置失效时间,默认是关闭浏览器后失效 4K左右 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 原生Cookie接口不友好,需要程序员自己封装 localStorage 除非被清除,否则永久保存 5MB左右 仅在客户端保存,不参与和服务器的通信 原生接口可以接受,也可以再次封装 sessionStorage 仅在当前会话下有效关闭页面或浏览器后被清除 5MB左右 仅在客户端保存,不参与和服务器的通信 原生接口可以接受,也可以再次封装 (10)Websocket
- 掌握 websocket 和 HTTP 的区别
- 相同点:HTTP 和 Websocket 都是基于TCP的应用层协议
- 不同点:
- websocket 是双向通信协议,模拟socket协议,可以双向发送和接受消息;HTTP 是单向的,通信只能由客户端发起。
- websocket 是需要浏览器和服务器通过握手建立连接,HTTP 是浏览器向服务器发送连接,服务器预先不知道这个连接。
- 联系:websocket 建立握手时需要基于 HTTP 进行传输,建立连接之后不再需要HTTP协议
(11)选择器
(12)边框与圆角
border-radius:水平半径/垂直半径
四个值:左上/右上/右下/左下
三个值:左上/右上和左下/右下
两个值:左上和右下/右上和左下
一个值:4角生效
(13)rgba
- rgba(r, g, b, a);
(14)盒子
- box-shadow: cx cy 模糊程度 扩展程度 颜色 内阴影;
- box-sizing:border-box;
(15)背景与渐变
- background:color position size repeat origin clip attachment image;
- background-image: linear-gradient(to方向/deg, color1 , color2);
(16)过渡
- transition:property duration timing-function delay;
(17)变换
- transition:property duration timing-function delay;
- rgba(r, g, b, a);
- 掌握 websocket 和 HTTP 的区别
- 掌握 cookie、Localstorage、 SessionStorage 三者区别
- worker 加载脚本文件 => 创建独立工作线程(主线程之外运行) => worker 线程运行结束把结果返回给主线程(处理计算密集型任务,优化主线程) =>浏览器提供JS多线程运行的宿主环境
- 使用 getCurrentPosition() 方法来获取用户的位置,从而实现队地理位置的定位
- 增加 select 元素(下拉选框)、textarea 元素(文本域)、button 元素(按钮)、datalist 元素(预定义选项列表)
- 增加 type 类型:color、date、datetime、datetime-local、email、month、number、range、search、tel、time 等
- 用途:
- 项目属性
- 侧轴对齐
-
- 主轴对齐
-
- flex 属性
- 浮动元素后添加空标签(不推荐)
-
- 解决:清浮动
- 特点:元素脱离了文档流,使父容器的高度塌陷,但是不脱离文本流
- 属性值前面添加元素(E)进一步限制,不添加元素(E)选择范围更广
- 否定伪类
- 结构伪类
- UI元素状态伪类
- 目标伪类
- 链接伪类
- 常用清浮动配置
- 清除浮动元素导致的高度塌陷,使页面布局正常显示
- 元素 float 脱离文档流移动(left/right),直到外边缘碰到包含框或另一个浮动框位置
- 兄弟盒子:相邻块级元素垂直外边距取大值
- 外边距合并:标准文档流中,块级元素 margin 在垂直方向出现叠加现象,大值覆盖小值
- 继承就是通过某种方式让一个对象可以访问另一个对象中的属性和方法
- 在实际编码过程中,很多类似方法存放于构造函数中,会导致内存浪费(内存泄漏),此时可以用继承解决
- fn.bind(this指向对象, 参数列表)
- fn.apply(this指向对象, 参数数组)
- fn.call(this指向对象, 参数列表)
- all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
- promise对象自带finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作,本质是then方法的特例
-
- 优点:
- 解决:Promise、async/await
- 函数也是一种变量,可以作为参数传给其他函数,在该外部函数中被调用以完成任务
- 标记清除法:分为标记和清除两个阶段,标记阶段需要从根节点遍历内存中的所有对象,并为可达的对象做上标记;清除阶段则把没有标记的对象(非可达对象)销毁
- 优点
- 本质是函数嵌套函数
- 全局执行上下文
- 原型链:如果某对象在自己和原型对象上都没有查到属性,通过__proto__属性继续查找原型对象的原型对象,尽头是Object.prototype,未找到返回undefined
- 面向对象编程是对程序的更高级别封装,高度复用
- 复杂数据类型存储在栈中的值是一个指针,指向存储对象的内存地址,涉及深浅拷贝问题
- 基本类型数据的值保存在栈中,对它进行拷贝时,为新变量开辟了新空间,数据互相不影响,不涉及深浅拷贝问题
- 隐式转换:某些运算符被执行时,系统自动转换
- Object.prototype.toString.call(obj):最准确,推荐使用
- obj.constructor:直接找到元素的构造函数类型
- obj instanceof Object :不适用基本类型判断
- typeof obj:不适用复杂类型判断,多显示object
- 通过new关键字创建的对象(系统对象、自定义对象)
- 复杂数据类型:在存储变量中存储地址,因此也叫引用数据类型,存放到堆(空间)
- 简单/基本数据类型:在存储变量中存储值本身,因此也叫值类型,存放到栈(空间)









