先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
正文
双飞翼布局
后我们来总结一下,双飞翼布局其实和圣杯布局的精髓是一样的,都是通过设置负margin来实现元素的排布。
- 不同的就是html结构,双飞翼是在middle元素内部又设置了一个milddle-inner并设置它的左右margin,而非圣杯布局的padding,来排除两边元素的覆盖。
- 双飞翼布局可以多了一个html结构,但是可以不用设置left,right元素的定位。
3. 请列举几种隐藏元素的方法
- visibility: hidden;这个属性只是简单的隐藏某个元素,但是元素占用的空间仍然存在
- opacity: 0; CSS3属性,设置0可以使一个元素完全透明,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如click事件,那么点击该区域,也能触发点击事件的
- display: none;元素会变得不可见,并且不会再占用元素位置。会改变页面布局。
- transform: scale(0);将一个元素设置为缩放无限小,元素将不可见,元素原来所在的位置将被保留。
4. 回流和重绘 (常见)
回流:当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做回流(重排)
重绘:
- 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘
- 触发:
- 改变元素的color、background、box-shadow等属性
5. 浏览器渲染机制
网页的生成过程,大致可以分成五步
- HTML 代码转化成 DOM
- CSS 代码转化成 CSSOM(CSS Object Model)
- 结合 DOM 和 CSSOM,生成一棵渲染树(包含每个节点的视觉信息)
- 生成布局(layout),即将所有渲染树的所有节点进行平面合成
- 将布局绘制(paint)在屏幕上
这五步里面,第一步到第三步都非常快,耗时的是第四步和第五步。
“生成布局”(flow)和"绘制"(paint)这两步,合称为"渲染"(render)
6. html5新特性、语义化(介绍html5–常见用自己话术总结)
html5新特性
音频video 视频 audio、画布canvas、H5存储localStorage sessionStorage
语义化标签 : header nav main article section aside footer
语义化意味着顾名思义,HTML5的语义化指的是合理正确的使用语义化的标签来创建页面结构 如 header,footer,nav,从标签上即可以直观的知道这个标签的作用,而不是滥用div。
语义化的优点有:
- 代码结构清晰,易于阅读,利于开发和维护
- 方便其他设备解析(如屏幕阅读器)根据语义渲染网页。
- 有利于搜索引擎优化(SEO)
7. css盒子模型
CSS 盒模型本质上是一个盒子,盒子包裹着HTML 元素,盒子由四个属性组成,从内到外分别是:content 内容、padding 内填充、border 边框、外边距 margin
两种盒模型的区别
标准盒模型:
width = content-width
height = content-height
怪异盒模型:
width = content-width + padding-width + border-width
height = content-height + padding-height + border-height
如何在CSS 设置这两个模型
标准盒模型:
box-sizing: content-box
怪异盒模型:
box-sizing: border-box
8.请描述一下 cookies sessionStorage和localstorage区别(常见)
**相同点:**都存储在客户端
**不同点:**1.存储大小
· cookie数据大小不能超过4k。
· sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2.有效时间
· localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
· sessionStorage 数据在当前浏览器窗口关闭后自动删除。
· cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- 数据与服务器之间的交互方式
· cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
9. 优先级
!important > 内联 > ID 选择器 > 类选择器 > 标签选择器。
- 每个选择器都有权值,权值越大越优先
- 继承的样式优先级低于自身指定样式
- 权值相同时,靠近元素的样式优先级高 顺序为内联样式表(标签内部)> 内部样式表(当前文件中)> 外部样式表(外部文件中)
10. BFC (会问到 概率也挺高–简单话术描述)
总结:BFC就是块级格式化上下文,让元素成为一个独立的空间 不受外界影响也不影响外面布局
BFC概念 也叫【块级格式化上下文】,简单来说,BFC 是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。
BFC是CSS布局的一个概念,是一个环境,里面的元素不会影响外面的元素。
BFC的布局规则
内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算
如何创建BFC
1、float的值不是none。
2、position的值不是static或者relative。
3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
4、overflow的值不是visible
BFC作用 (解决了什么问题)
- 阻止margin重叠
- 可以包含浮动元素 —— 清除内部浮动
- 自适应两栏布局
- 可以阻止元素被浮动元素覆盖
11. CSS3的新特性 (或者问介绍一下css3)
css3新特性 | 描述 |
box-shadow | 盒子阴影 |
border-radius | 圆角 |
box-sizing | 盒子模型 |
linear-gradient, radial-gradient | 渐变 |
transition | 过渡 |
animate | 动画 |
transform | 2D 转换/3D 转换 |
iconfont | 字体图标 |
flex | 弹性布局 |
12. var let const 的区别?(常见问题-最基本问题)
- const 定义常量, 不可以重复赋值 块级作用域 不存在变量提升
- var 定义变量,可以重复声明 var 全局作用域或函数作用域 有变量提升
- let 定义变量,不可以重复声明 , 块级作用域 不存在变量提升
13. javascript 有哪些基础数据类型?
- 基础数据类型String、Number、Boolean、Undefined、Null
- 引用数据类型: Object、Array、Function、Date等
- Symbol、BigInt是ES6之后新增的 属于基本数据类型
- Symbol
指的是独一无二的值
-
- BigInt
是一种数字类型的数据,它可以表示任意精度格式的整数
14. null和undefined区别
- 首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
- undefined 代表的含义是
未定义,一般变量声明了但还没有定义的时候会返回 undefined
- null 代表的含义是
空对象。null主要用于赋值给一些可能会返回对象的变量,作为初始化。
15. == 与 === 的区别?
- 双等号(==)进行相等判断时,如果两边的类型不一致,会强制类型转化再进行比较。
- 三等号(===)进行相等判断时,如果两边的类型不一致,不强制类型准换,直接返回 false
16. js中那些数据在 if 判断时是 false
- 0、“”、false、null、undefined、NaN 判断为false (6个)
- 其他皆为true
注意:下面的判断结果
[]==false 和 ![]==false true
第一个 []false 转为数字 00
第二个 ![]false 转为布尔 falsefalse
[]==[] – >false
js中布尔值为false的六种情况
下面6种值转化为布尔值时为false,其他转化都为true
1、undefined(未定义,找不到值时出现)
2、null(代表空值)
3、false(布尔值的false,字符串"false"布尔值为true)
4、0(数字0,字符串"0"布尔值为true)
5、NaN(无法计算结果时出现,表示"非数值";但是typeof NaN===“number”)
6、“”(双引号)或’’(单引号) (空字符串,中间有空格时也是true)
注意空数组空对象,负值转的布尔值时都为true
17. 判断数据类型的方法有哪些,有什么区别 (常见)
判断数据类型的方法 | 描述 |
typeof | 判断基础数据类型(数组、对象、null都会被判断为object) |
instanceof | 判断引用数据类型,不能判断基本数据类型 |
constructor | 判断数据的类型 |
Object.prototype.toString.call() | 使用 Object 对象的原型方法 toString 来判断数据类型 |
JavaScript类型判断的四种方法
一、typeof
typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。
返回的结果用该类型的字符串(全小写字母)
用于判断数据类型,返回值为6个[字符串],分别为string、Boolean、number、function、object、undefined。
console.log(typeof undefined) // undefind
console.log(typeof null) // object
console.log(typeof true) // boolean
console.log(typeof 43) // number
console.log(typeof ‘21’) // string
console.log(typeof {a:1}) // object
console.log(typeof Symbol()) // symbol
console.log(typeof 123n) // bigint
function a() {}
console.log(typeof a) // function
var date = new Date()
var error = new Error()
console.log(typeof date) // object
console.log(typeof error) // object
二、instanceof
instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型
instanceof用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象,否则会报错!其返回值为布尔值
通俗一些讲,instanceof 用来比较一个对象是否为某一个构造函数的实例。注意,instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型
console.log(12 instanceof Number) // false
console.log(‘22’ instanceof String) // false
console.log(true instanceof Boolean) // false
console.log(null instanceof Object) // false
console.log(undefined instanceof Object) // false
console.log([] instanceof Array) // true
console.log({a: 1} instanceof Object) // true
console.log(json instanceof Object) // true
function a() {}
console.log(a instanceof Function) // true
console.log(new Date() instanceof Date) //true
console.log(reg instanceof RegExp) //true
console.log(error instanceof Error) // true
三、Object.prototype.toString.call()
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
console.log(Object.prototype.toString.call(1)) // [object Number]
console.log(Object.prototype.toString.call(1n)) // [object BigInt]
console.log(Object.prototype.toString.call(‘123’)) // [object String]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(function a() {})) // [object Function]
console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
console.log(Object.prototype.toString.call(Math)) // [object Math]
console.log(Object.prototype.toString.call(JSON)) // [object JSON]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(new RegExp())) // [object RegExp]
console.log(Object.prototype.toString.call(new Error)) // [object Error]
console.log(Object.prototype.toString.call(window) // [object Window]
console.log(Object.prototype.toString.call(document) // [object HTMLD
四、constructor
constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。 constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。
constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。
constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,
一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,
一般要同时修改constructor属性的指向。
console.log(‘22’.constructor === String) // true
console.log(true.constructor === Boolean) // true
console.log([].constructor === Array) // true
console.log(document.constructor === HTMLDocument) // true
console.log(window.constructor === Window) // true
console.log(new Number(22).constructor === Number) // true
console.log(new Function().constructor === Function) // true
console.log((new Date()).constructor === Date) // true
console.log(new RegExp().constructor === RegExp) // true
console.log(new Error().constructor === Error) // true
注意:
1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
2、函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
18. JS垃圾回收 (常见)
有两种垃圾回收策略:
- 标记清除:
标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。
- 引用计数:
它把对象是否不再需要简化定义为对象:有没有其他对象引用到它。如果没有引用指向该对象(引用计数为 0),对象将被垃圾回收机制回收。
19. 深拷贝、浅拷贝(笔试题)
【{},[]】
- 浅拷贝: 以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响
- Object.assign
- 展开运算符 …
- 深拷贝: 完全拷贝一个新对象,修改时原对象不再受到任何影响
- JSON.parse(JSON.stringify(obj)): 性能最快
具有循环引用的对象时,报错
当值为函数、undefined、或symbol时,无法拷贝
-
递归进行逐一赋值
-
lodash工具库:cloneDeep
深拷贝:
arr=[100, [{a : ‘hello’}, {b : “world”}], { c: “123456789” }];
//判断修改的是不是’object’或者null,如果不是 object 或者 null 那么直接返回
function deepClone(obj = {}) {
if (typeof obj !== ‘object’ || obj == null) {
return obj;
}
let result;
//判断上面下来的obj是不是数组 用instanceof来检测 因为是数组应用类型
obj instanceof Array?result=[]:result={}
for (var item in obj) {
//查找一个对象是否有某个属性
if (obj.hasOwnProperty(item)) {
// 递归调用
result[item] = deepClone(obj[item])
}
}
return result;
}
let arr1=deepClone(arr);
arr1[1][0].a=‘vue’
arr1[0]=99
console.log(‘原数组’,arr)
console.log(‘新数组’,arr1)
20. 数组的方法
数组的方法 | 描述 |
map | 遍历数组,返回回调返回值组成的新数组 |
forEach | 无法break,可以用try/catch中throw new Error来停止 |
filter | 过滤 |
some | 有一项返回true,则整体为`true |
every | 有一项返回false,则整体为`false |
join | 通过指定连接符生成字符串 |
push / pop | 末尾推入和弹出,改变原数组。push 返回数组长度, pop 返回原数组最后一项; |
unshift / shift | 头部推入和弹出,改变原数组,unshift 返回数组长度,shift 返回原数组第一项 ; |
sort(fn) / reverse | 排序与反转,改变原数组 |
concat | 连接数组,不影响原数组, 浅拷贝 |
slice(start, end) | 返回截断后的新数组,不改变原数组 |
splice(start, number, value…) | 返回删除元素组成的数组,value 为插入项,改变原数组 |
indexOf / lastIndexOf(value, fromIndex) | 查找数组项,返回对应的下标 |
reduce / reduceRight(fn(prev, cur), defaultPrev) | 两两执行,prev 为上次化简函数的return值,cur 为当前值 当传入 defaultPrev 时,从第一项开始; 当未传入时,则为第二项 |
21. js数组去重,能用几种方法实现?(笔记题)
- 使用es6 set方法
[…new Set(arr)]
let arr = [1,2,3,4,3,2,3,4,6,7,6]; let unique =(arr)=>[…newSet(arr); unique(arr);//[1,2,3,4,6,7]
-
利用新数组indexOf查找indexOf()方法可返回某个指定的元素在数组中首次出现的位置。如果没有就返回-1。
-
for双重循环通过判断第二层循环,去重的数组中是否含有该元素,如果有就退出第二层循环,如果没有j==result.length就相等,然后把对应的元素添加到最后的数组里面。
22. 作用域、作用域链
作用域:变量和函数起作用的范围。
作用域链:是js查找方式,决定的变量和函数向上查找的范围。
- 作用域是可访问的变量的
集合。在JavaScript中,作用域为可访问变量,对象,函数的集合,它分为局部作用域和全局作用域。作用域决定了这些变量的可访问性(可见性)。
作用域链
- 我们可以在执行上下文中访问到父级甚至全局的变量,这便是作用域链的功劳。作用域链可以理解为一组对象列表,包含
父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。
-
- 它由两部分组成:
- [[scope]]属性: 指向父级变量对象和作用域链,也就是包含了父级的[[scope]]和AO
- AO: 自身活动对象
- 如此 [[scope]]包含[[scope]],便自上而下形成一条 链式作用域。
23. 构造函数、实例
- 构造函数:可以通过
new来 新建一个对象 的函数
- 实例: 通过构造函数和
new创建出来的对象,便是实例。 实例通过__proto__指向原型,通过constructor指向构造函数。
24. 原型、原型链? (常问)
1.原型: 对象中固有的__proto__属性,该属性指向对象的prototype原型属性。
原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是Object.prototype所以这就是我们新建的对象为什么能够使用toString()等方法的原因
原型:
- 一个简单的对象,用于实现对象的属性继承。
- 每个JavaScript对象中都包含一个__proto__的属性指向该对象的原型,可obj.__proto__进行访问。
原型链
- 原型链是由原型对象组成,每个对象都有 __proto__ 属性,(该属性指向对象的prototype原型属性)指向了创建该对象的构造函数的原型,__proto__ 将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。
25. this指向 (常问–用话术藐视出来才可以噢-加油)
this的指向主要有下面几种:
1、this出现在全局函数中,永远指向window
2、this出现在严格模式中 永远不会指向window
3、当某个函数为对象的一个属性时,在这个函数内部this指向这个对象
4、this出现在构造函数中,指向构造函数实例
5、当一个元素被绑定事件处理函数时,this指向被点击的这个元素
6、this出现在箭头函数中时,this和父级作用域的this指向相同
26. call、apply、bind
三者区别
- 三者都可以改变函数的this对象指向
- 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局window
- 三者都可以传参,
- call是参数列表,apply是数组,call和apply是一次性传入参数,
- bind是参数列表,但可以分为多次传入参数
- bind是返回绑定this之后的函数,apply、call 则是立即执行
应用场景
- call 经常做继承。
- apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
- bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。
27. 闭包、闭包的使用场景
闭包的概念:
闭包:是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性
1.函数内再嵌套函数 2.内部函数可以引用外层的参数和变量 3.参数和变量不会被垃圾回收机制回收
闭包的优缺点
- 优点:延长变量生命周期、私有化变量
- 缺点:过多的闭包可能会导致内存泄漏
闭包的应用场景
- ajax请求的成功回调
- 事件绑定的回调方法
- setTimeout的延时回调
- 函数内部返回另一个匿名函数
- 函数节流、防抖 封装模块
28. 箭头函数和普通函数的区别
- 箭头函数比普通函数更加简洁
- 箭头函数没有自己的this
- 箭头函数继承来的this指向永远不会改变
- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的arguments
- 箭头函数没有prototype
- call()、apply()、bind()等方法不能改变箭头函数中this的指向
29. forEach和map方法有什么区别
- forEach()方法会针对每一个元素执行提供的函数,对数据的操作会改变原数组,该方法没有返回值;
- map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值;
注意:
- forEach()会改变原数组的方法
- 参数:item数组中的当前项,index当前项的索引,array原始数组;
- 数组中有几项,那么传递进去的匿名回调函数就需要执行几次
使用场景:当我们对数组的元素进行处理时(例如:增加元素,元素值改变),可以使用这个函数
注意:
item数组中的当前项,index当前项的索引,array原始数组
map的回调函数中支持return返回值,return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆了一份,把克隆这一份的数组中的对应项改变了 );
map会改变原数组的方法,
map的执行速度更快,比forEach的执行速度快了70%;
使用场景:
map适用于你要改变数据值的时候,不仅在于它更快,而且返回一个新的数组,这样可以提高复用性(map(),filter(),reduce())等组合使用。
var arr = [1, 2, 3, 4, 5];
var newArr = arr.map(num => num * 2).filter(num => num > 5);
// newArr = [6, 8, 10]
总结:
- 能用forEach()做到的,map()同样可以。反之亦成立
- map()会分配内存空间存储新数组并返回,forEach()不会返回数组
- forEach()允许callback更改原始数组的元素。而map()返回新的数组
30. promise理解、手写promise
- Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,避免了地狱回调
- Promise有三种状态: pending(等待态),fulfilled(成功态),rejected(失败态) ;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
- Promise拥有一个then方法,用以处理resolved或rejected状态下的值
- then方法接收两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败时的回调。
- then方法返回一个新的Promise对象,因此可以通过链式调用then方法
function xxx(onResolved) {
// 这里叫做promise2
return new Promise((resolve,inject) => {
//计时器模拟请求
setTimeout(()=>{
if(){
resolve(res)
} else{
inject(err)
}
})
});
};
xx.then(fun,fun)
31. async await函数
- async/await函数是异步代码的新方式
- async/await是基于promise实现的
- async/await使异步代码更像同步代码
- await 只能在async函数中使用,不能再普通函数中使用,要成对出现
- 默认返回一个promise实例,不能被改变
- await下面的代码是异步,后面的代码是同步的
32. 防抖和节流
本质上是优化高频率执行代码的一种手段
如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(防抖)和debounce(节流)的方式来减少调用频率
定义:
- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流。
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖。
防抖应用场景
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测 onchange / oninput事件
- 窗口大小计算。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流应用场景
- 懒加载、滚动加载、加载更多或监听滚动条位置;
- 百度搜索框,搜索联想功能;
- 防止高频点击提交,防止表单重复提交;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
it 只能在async函数中使用,不能再普通函数中使用,要成对出现
5. 默认返回一个promise实例,不能被改变
6. await下面的代码是异步,后面的代码是同步的
32. 防抖和节流
本质上是优化高频率执行代码的一种手段
如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(防抖)和debounce(节流)的方式来减少调用频率
定义:
- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流。
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖。
防抖应用场景
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测 onchange / oninput事件
- 窗口大小计算。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流应用场景
- 懒加载、滚动加载、加载更多或监听滚动条位置;
- 百度搜索框,搜索联想功能;
- 防止高频点击提交,防止表单重复提交;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-4w1InHOP-1713270292135)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!