当前位置: 首页 > news >正文

前端基础面试题·第三篇——JavaScript(其三)

1.字符串

(1) 常用方法

    1.charAt(index) 返回指定位置的字符,若没找到,则返回空2.charCodeAt(index) 返回指定位置的unicode字符编码,若没找到,则返回空 3.String.concat(str1,str2) 连接多个字符串,并返回新字符串4.String.fromCharCode(code1) 根据unicode编码,返回字符串5.indexOf(str) 返回str第一次出现的位置,若没找到,则返回-16.lastIndexOf(str) 返回str最后一次出现的位置,若没找到,则返回-17.match(regexp) 返回匹配的字符串,若没找到,则返回null8.search(regexp) 基于正则表达式返回字符串,返回匹配的第一个字符串的·位置10.slice(start,end) 截取字符串,返回新字符串,不含end11.split(str,limit) 按照str分割字符串,返回新数组,limit为切割的最大数量12.substr(start,length) 截取字符串,返回新字符串13.substring(start,end) 截取字符串,返回新字符串(这个函数与slice基本相同,但这个函数支持start > end,相当于支持逆向截取)14.toLowerCase() 返回小写字符串15.toUpperCase() 返回大写字符串16.trim() 去除字符串两端的空格17.trimLeft() 去除字符串左边的空格18.trimRight() 去除字符串右边的空格19.codePointAt(index) 返回指定位置的unicode编码20.fromCodePoint(code) 根据unicode编码,返回字符串21.replace(str,str2){1.基础用法:本函数基本用法是传入两个参数,匹配字符串中第一个参数,将其替换为第二个参数,返回一个新字符串,不会改变原字符串2.初级用法:第一个参数可以传入正则表达式,同时第二个参数中可以写入部分特殊的符号,用于匹配特殊的部分,基本如下:$& -> 该符号报能获取到第一个参数匹配到的字符串var sStr='讨论⼀下正则表达式中的replace的⽤法';sStr.replace(/正则表达式/,'《$&》');// 得到:"讨论⼀下《正则表达式》中的replace的⽤法"$` -> 获取到匹配项左侧的剩余子串  `var sStr='讨论⼀下正则表达式中的replace的⽤法';sStr.replace(/正则表达式/,'《$`》');// 得到:"讨论⼀下《讨论⼀下》中的replace的⽤法"$' -> 获取到匹配项右侧的剩余子串'var sStr='讨论⼀下正则表达式中的replace的⽤法';sStr.replace(/正则表达式/,"《$'》");// 得到:"讨论⼀下《中的replace的⽤法》中的replace的⽤法"$n -> n为数字,获取到第n个匹配项的字符串var sStr='讨论⼀下正则表达式中的replace的⽤法';sStr.replace(/正则表达式/g,'《$1》');// 得到:"讨论⼀下《正则表达式》中的replace的⽤法"3.高级用法: 本函数第二个参数中可以传入一个回调函数,字符串中匹配了多少次,函数就会执行多少次函数参数:第一参数:匹配的字符串第二参数:匹配的字符串的索引第三参数:原字符串这里需要注意,在匹配函数中使用正则表达式并使用分组匹配,这里从第一个参数开始就会将匹配到的每一组都作为参数,直到匹配项传完之后紧接着就会传入上面提到的第二第三22.repeat(num) 返回字符串重复num次后的新字符串

2.事件流

在dom事件模型中,一个事件发生后,会在子元素与父元素之间传播,这个传播的过程就是事件流。
一般分为三个阶段:

  1. 事件捕获:事件从最外层的父元素开始,一直传播到目标元素
  2. 事件目标:事件到达目标元素
  3. 事件冒泡:事件从目标元素开始,一直传播到最外层的父元素

两种事件

1.事件捕获:

触发元素的事件时,该事件从该元素的祖先元素传递下去。 (不太具体的节点应该更早接收到事件,⽽最具体的节点最后收到事件)

2.事件冒泡:

到达此元素之后,⼜会向其祖先元素传播上去 DOM标准规定事件流包括3个阶段:事件捕获、处于⽬标阶段和事件冒泡。

事件委托

事件委托就是利⽤事件冒泡,只指定⼀个事件处理程序,就可以管理某⼀类型的所有事

事件模型

1.原始事件模型

    var btn = document.getElementById('.btn');btn.onclick = fun;//移除方式btn.onclick = null;

事件处理直接绑定在元素上,只支持事件冒泡,不支持事件捕获
同一类型的事件,只能绑定一次。

2.标准事件模型

    addEventListener(eventType, handler, useCapture)// 移除方式removeEventListener(eventType, handler, useCapture)eventType指定事件类型(不要加on)handler是事件处理函数useCapture是boolean类型⽤于指定是否在捕获阶段进⾏处理,⼀般设置为falseIE浏览器保持⼀致

事件捕获:从document⼀直向下传播到⽬标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执⾏。
事件处理:到达⽬标元素, 触发⽬标元素的监听函数。
事件冒泡:从⽬标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执⾏。

支持冒泡的事件:

事件可否支持冒泡
click可以
dbclick可以
keydown可以
keyup可以
mousedown可以
mousemove可以
mouseout可以
mouseover可以
mouseup可以
scroll可以
blur不可以
focus不可以
resize不可以
about不可以
mouseenter不可以
mouseleave不可以
load不可以
unloadbukeyi

阻止冒泡

阻⽌冒泡⾏为:⾮ IE 浏览器 stopPropagation(),IE 浏览器 window. event. cancelBubble = true。

阻⽌默认⾏为:⾮ IE 浏览器 preventDefault(),IE 浏览器 window. event. returnValue = false。

3.事件代理及委托

把⼀个元素响应事件(click、keydown…)的函数委托到另⼀个元素,在冒泡阶段完成
相对于直接给⽬标注册事件,有以下优点:

  • 节省内存,减少dom操作
  • 不需要给⼦节点注销事件
  • 动态绑定事件

事件委托,会把⼀个或者⼀组元素的事件委托到它的⽗层或者更外层元素上,真正绑定事件的是外层元素,⽽不是⽬标元素。
适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup,keypress

4.HTMLCollection、NodeList

1.NodeList
NodeList对象是⼀个类数组对象,表示⽂档中⼀组有序的节点,⽤于获取⼀组动态变化的节点。

NodeList可以是动态的也可以是静态的,‌具体取决于获取它的方法。‌例如,‌Node.childNodes返回的是一个动态的NodeList,‌而document.querySelectorAll返回的是一个静态的NodeList。‌动态的NodeList(‌如Node.childNodes)‌会随着DOM结构的变化而自动更新。‌如果你在页面上添加或删除了节点,‌那么NodeList的长度和内容也会相应地更新。‌相反,‌静态的NodeList(‌如通过document.querySelectorAll获取的)‌不会因为DOM的变化而自动更新,‌即使页面上的元素数量发生了变化,‌NodeList的长度和内容也不会改变23。‌

2.HTMLCollection
HTMLCollection对象是⼀个类数组对象,表示⽂档中⼀组有序的元素,⽤于获取⼀组静态的元素
HTMLCollection通常是通过getElementsByTagName等方法获取的,‌它是一个动态集合(‌live collection)‌。‌这意味着,‌如果页面的DOM结构发生改变(‌例如添加或删除元素)‌,‌HTMLCollection会自动更新以反映这些变化。‌例如,‌如果你使用getElementsByTagName获取了一组

  • 元素,‌然后在页面上动态地添加或删除了
  • 元素,‌那么HTMLCollection的长度和内容也会相应地更新。‌
  • 5.Element、Node

    1.Element

    Element对象是Document对象的⼀个节点,表示的是整个文档树中的⼀个节点。

    Element对象是document对象中所有节点的父节点,它有如下属性:

    • tagName:元素标签名,如div、span等
    • attributes:元素属性集合,如class、id等
    • children:元素子节点集合,如div中的span等
    • outerHTML:元素标签及其子节点,如html<div class="box"><span>123</span></div>
    • innerHTML:元素标签中的子节点,如html<span>123</span>

    2.Node

    Node对象是DOM树中的节点,表示的是整个文档树中的⼀个节点。

    Node对象是Element对象的父节点,它有如下属性:

    • parentNode:节点的父节点
    • childNodes:节点的子节点集合
    • nextSibling:节点的下一个兄弟节点
    • previousSibling:节点的上一个兄弟节点
    • nodeName:节点的名称,如div、span等
    • nodeValue:节点的值,如文本内容

    Node是基类,Element、Text都继承于它

    6.事件监听

    1.onclick类型

    onclick类型的事件会绑定到指定的dom元素上,当用户点击该元素时,就会触发事件处理函数,由于这个方式出现的比较早,所以基本上所有浏览器都兼容。

    2.addEventListener类型

    这种方式用于向文档添加事件句柄(简单来说这个方法就是将需要执行的事件监听函数添加到当前元素的事件监听集合中,以处理指定类型的事件。)这里需要注意的是这个方法可以为一个元素多次添加事件监听,这些事件监听函数都会触发(并且所填加的事件处理函数触发先后顺序并不是代码书写顺序)

        const div = document.querySelector('div');function fn() { console.log(1);}div.addEventListener("click",fn,true) // 1div.addEventListener("click",fn,true) // 2div.addEventListener("click",()=> {console.log(13);}) // 3div.addEventListener("click",()=> {console.log(14);}) // 4
    

    如上面代码所示div元素添加了4个click事件监听,正常情况下,这4个监听函数都会触发。但由于第一和第二个事件监听都用的是fn函数,同时两个事件监听类型,是否冒泡等三个参数均为相同,这就会导致这两个事件监听只会有一个生效。(注意,这里的三个参数相同一定指简单类型和引用类型参数两者都是相同的,如上面代码中的第三第四个监听事件,虽然代码写法完全一致,但由于是在参数位置直接传入现定义的函数,故两者第二个参数是不同的,因此3,4均会执行)。针对以上代码的执行顺序,可以总结为:

    1. 先执行第三个参数为true的事件监听(若有多个,按代码书写顺序执行)
    2. 在按代码书写顺序执行第二个参数为false的事件监听

    3.两者的区别

    1. 兼容性: onclick兼容所有浏览器, 添加事件监听兼容IE9及以上浏览器
    2. 重复性: onclick只能执行一个事件监听,如果多次添加,只有最后一次生效。addEventListener可以添加多个事件监听,并且不会覆盖(相对来说,具体情况看上述代码解析)
    3. 书写方式: onclick可以作为一个dom属性添加到Html元素上,因此可以直接在html中书写,也可以在js中书写。但addEventListener必须写在js中,且只能写在js中,这个方法主要是为dom元素的事件监听集合中添加监听事件,他被挂载在dom的原型上,因此可以直接使用。
    4. 触发顺序: onclick事件监听函数触发顺序是按照代码书写顺序执行,addEventListener事件监听函数触发顺序是根据添加的先后顺序执行。(这里的添加顺序的规则主要是先会将所有capture为true的事件添加到一个执行队列,然后才会从头开始再将剩余的事件添加到队列,当触发事件时会依次从队列中取出事件来执行)
    5. 移除方式: onclick一般会将值社外置位null来移除监听事件。addEventLister必须通过removeEventListener来移除监听事件,且第二个参数和第三个参数要与添加时一致。

    7.页面生命周期

    1.页面生命周期

    HTML页面生命周期包含四个主要事件:

    1. DOMContentLoaded事件,HTML文档dom树的解析已经完毕并构建了Dom树,但外部CSS,图片文件可能还没有完全加载完成。
      此时当浏览器遇到script标签时,就会停止html解析,转而开始下载解析js。因为脚本可能想要修改DOM,对其执⾏write操作,所以DOMContentLoaded必须等待脚本执⾏结束(这就是js阻塞渲染的原因)。
      为script标签添加以下两个属性就可以放止渲染阻塞

      async: 添加这个属性浏览器就会新开一个线程去开始下载脚本文件,并在脚本下载完成之后立即执行。

      defer: 添加这个属性浏览器就会新开一个线程去开始下载脚本文件,但这个属性会使得浏览器在下载完脚本文件之后会等到html解析完成后再执行。

      外部样式表不会影响DOM,因为DOMContenLoaded不会等待他们。
      但是,如果在样式后⾯有⼀个脚本,那么该脚本必须等待样式表加载完成,原因是,脚本可能想要获取元素的坐标或其他与样式相关的属性。

    2. load事件,页面所有资源加载完毕,包括图片、CSS文件等。
      当整个⻚⾯,包括样式、图⽚和其他资源被加载完成时,会触发 window 对象上的 load 事件。可以通过 onload属性获取此事件。

    3. beforeunload事件,页面即将被卸载。
      如果访问者触发了离开⻚⾯的导航(navigation)或试图关闭窗⼝,beforeunload 处理程序将要求进⾏更多确。
      认。
      如果我们要取消事件,浏览器会询问⽤户是否确定。

    4. unload事件,页面已经卸载。

    8.异步

    1.同步和异步

    • 同步: 浏览器在执行js代码的时候,会按顺序执行,再继续执行后续的js代码。即同一时间只执行一段代码,前一个任务必须执行完毕,才能执行后一个任务。
    • 异步:当程序执⾏到异步的代码时,会将该异步的代码作为任务放进任务队列,⽽不是推⼊主线程的调⽤栈。等主线程执⾏完之后,再去任务队列⾥执⾏对应的任务。优点是:不会阻塞后续代码的运⾏。

    常见场景

    1. 定时任务
    2. 网络请求
    3. 事件监听

    解决方案

    1. 回到函数-回调函数就是将异步代码封装成函数,在需要的时候调用,这样就可以保证异步代码在同步代码执行之后执行。这个最大的缺点就是当需要执行很多的异步代码时会造成代码的嵌套层数很深,代码可读性极差,俗称回调地狱

    Promise

    promise时在ES6中引入的一种专门用异步处理的解决方案,他本身是一个对象类型,通过new操作符就可以创建一个promise对象,这个对象中包含三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

    当一个异步操作操作执行后,就可以通过某种方式来改变promise的状态。

    当promise的状态为fulfilled时,可以通过then方法来获取promise对象的结果,当promise的状态为rejected时,可以通过catch方法来获取promise对象的结果。

    Promise构造函数接受一个回调函数作为参数,回调函数会挂载两个参数,这连个参数都是回调函数,分别为resolve,reject。调用这个两个函数就会改变promise的状态。

    resolve() 会将promise对象的状态从pending变为fulfilled,reject()会将promise对象的状态从pending变为rejected。

    因此就可以Promise参数回调函数的位置来执行异步操作,并且判断异步操作是否成功,如果成功就调用resolve(),否则调用reject()。

    然后Promise就会返回一个promise对象,如果构造函数中回调函数中异步逻辑执行了,那么这promise的状态就会永久性的敲定,然后我们可以在他的then与catch中通过回到函数来监听promise中状态的改变,从而执行相关的逻辑操作。then中需要擦混入一个回调回调函数,回调函数会被挂载上一个参数res,这个参数就是在前面创建promise中异步代码所执行的结果。catch中也需要擦混入一个回调回到函数,会为回调函数挂载一个err参数,改参数代表若前面异步代码执行出错后的出错原因。

    同时then与catch其实不会同时执行,而是会根据promise对象的状态来决定执行哪个回调函数。

    promise对象本身还有一个方法,不管是异步操作是否成功,都会执行,即finally方法,该方法同样需要传入一个回调函数,这个回调函数在promise对象状态改变后都会执行。

    需要注意的是以上三个方法都返回一个新的promise对象,这个对象的状态会取决于各自的回调函数中的操作。因此这样一来就可以通过链式调用,将多个异步操作串起来。

    async/await

    前面这种promise的方法来处理异步操作确实比单纯的使用回调函数方便很多,但由于链式编程的原因,我们还是在依赖回调函数来处理,通过链式调用还会造成代码可读性降低。因此,ES7中引入了async/await来处理异步操作。这其实是promise的封装语法糖,首先他的运行必须是在一个函数中,然后通过async将该函数标记为异步函数,在函数中执行异步操作的代码前面添加await关键字,原本需要通过then方法获取一步结果,现在就可以直接由原本的异步操作直接返回(本质上这里其实是js引擎等待异步代码执行完毕后获取到结果在返回,并不是同步执行,只不过还将回调函数变为了底层自动处理,减少了代码书写量),同样如果是catch方法获取数据,await也会直接获取到。

    Promise类的其他方法

    1. Promise.Reject() 直接拒绝,返回一个状态为rejected的promise对象
    2. Promise.Resolve() 直接通过,返回一个状态为fulfilled的promise对象
    3. Promise.all() 接受一个promise对象的数组,只有当数组中的所有promise对象的状态都为fulfilled时,返回的promise对象的状态才会为fulfilled,否则返回的promise对象的状态就会为rejected,且返回的promise对象的结果为第一个rejected的promise对象的结果。
    4. Promise.race() 接受一个promise对象的数组,只要数组中有一个promise对象的状态改变,那么返回的promise对象的状态就会改变,且返回的promise对象的结果为第一个改变状态的promise对象的结果。

    9.生成器(Generator)与迭代器(Iterator)

    1.迭代器

    迭代器,又称迭代器对象,是ES6中新增的一种数据类型。它为js中各种不同的数据结构(Array、Set、Map)提供统⼀的访问机制。部署了Iterator接⼝,就可以完成遍历操作。 因此iterator也是⼀种对象,不过相⽐于普通对象来说,它有着专为迭代⽽设计的接⼝。
    更具体地说,迭代器是通过使用 next() 方法实现了迭代器协议的任何一个对象,该方法返回具有两个属性的对象:

    • 一个是value,表示当前迭代器的值
    • 一个是done,表示当前迭代器的状态(这是一个boolean值,当为false时表示迭代序列还可以继续迭代,当为true是表示迭代已经到了最终值)
      迭代器对象最主要的方法就是通过next()不断重复的调用获取迭代器对象中的下一个值。

    2.生成器
    生成器,又称生成器函数,是ES6中新增的一种函数类型。

    生成器函数与普通函数不同,生成器函数通过function关键字后加一个*号来标识。最初生成器函数不会执行任何逻辑,里面的代码也不会执行,而是在调用生成器函数后会返回一个特殊的迭代器,这个迭代器就被称为生成器。我们接下来调用这个生成器的next() 方法,就会消费掉这个生成器,然后生成器函数中的逻辑才会执行,执行过程中遇到第一个yield语句就会暂停函数代码的执行,从而又返回一个生成器,以此类推,直到整个函数执行完毕。

    返回的生成器函数的值就是yield语句后面的值(这个关键字和return关键字很像,但他不会结束函数运行,而是暂停函数运行,返回生成器)

    3.可迭代对象

    若一个对象拥有迭代行为,则被称为可迭代对象。如js内置的Array、Set、Map等。为了实现迭代,这个对象必须部署了Symbol.iterator属性,该属性返回一个迭代器。

    for … of就是采用对象的Symbol.iterator属性来遍历可迭代对象。

    • 手写for…of
       function forOf(obj,callback) {let iterator =  obj[Symbol.iterator]()while(true) {const res = iterator.next()if(res.done) break;callback(res.value)}}forOf([1,2,3,4,5],(data) => {console.log(data);})
    

    对于原本不具有迭代器的对象,我们可以通过部署Symbol.iterator属性来使其具有迭代器行为。

       const obj  = {}obj[Symbol.iterator] = function* () {yield 1yield 2yield 3}for(let i of obj) {console.log(i);}
    

    4.yield与return异同点

    相同点: 都可以返回值,且都会暂停函数执行。
    不同点: yield可以返回多次值,而return只能返回一次值。
    都能返回紧跟在语句后⾯的那个表达式的值
    yield相⽐于return来说,更像是⼀个断点。遇到yield,函数暂停执⾏,下⼀次再从该位置继续向后执⾏,⽽
    return语句不具备位置记忆的功能。
    ⼀个函数⾥⾯,只能执⾏⼀个return语句,但是可以执⾏多次yield表达式。
    正常函数只能返回⼀个值,因为只能执⾏⼀次return;Generator 函数可以返回⼀系列的值,因为可以有任意多个yield

    特别注意:箭头函数不可以做生成器函数。

    手写模块

    1. 手写数组forEach方法
        Array.prototype.myForEach = function (callback) {// 获取迭代器对象const iterator = this[Symbol.iterator]()let index = 0while(true) {const res = iterator.next()if(res.done) break;callback(res.value,index,this)index++}}
    

    10.定时器

    1.setTimeout;

    setTimeout(⭐ 必选参数) 是一个挂载到全局对象上的一个方法,他开启一个定时器(这里我更加习惯叫他延时器),定时器会在一定时间之后执行,同时本身返回一个定时器的ID,使用该ID我们可以取消定时器的设置。

    参数:

    1. functionRef: 定时器到需要执行的函数逻辑
    2. delay: 延时时间,单位是毫秒,如果不传这个这个 参数,默认是0,这个值有一个最小值就是4ms,如果小于这个值,会被自动设置为4ms,0除外
    3. param1, …, paramN: 此后的参数都是作为定时器所执行的函数的参数传递

    返回:

    1. 定时器的ID,可以用来取消定时器(这个ID本质上是一个正整数。

    取消:

    setTimeOut的取消可以调用全局对象上的clearTimeout方法,该方法接收一个参数,就是定时器的ID。

    this指向:

    由 setTimeout() 执行的代码是从一个独立于调用 setTimeout 的函数的执行环境中调用的。为被调用的函数设置 this 关键字的通常规则适用,如果你没有在调用中或用 bind 设置 this,它将默认为 window(或 global)对象。
    简单来说就是对于传入的函数this指向全局对象,如果需要改变this指向,可以对传入的函数使用bind方法。

    注意: 不能为setTimeout使用call等方法来改变其this,因为setTimeout是挂载在全局对象上的,而call等方法会改变this指向,这是不被允许的,就算改变了setTimeout的this指向,其中调用的函数还是指向全局对象,因为两者在调用时不是处于同一执行环境中。

    解决方法:这里可以使用包装函数来解决this问题,也可以使用箭头函数,或者bind方法

        setTimeout(function() {obj.fn() // 这样fn就指向obj了})setTimeout(obj.fn) // 这样fn中的this指向全局对象
    //也可以这样写setTimeout(obj.fn.bind(obj)) // 这样fn中的this指向objsetTimeout(() => {obj.fn() // 这样fn中的this指向ob})
    

    这里还有一个需要注意的点,就是setTimeout执行函数的位置本质上可以传入一个可执行的js字符串代码,与eval相似,但是现存许多安全问题,因此许多文档中不建议使用,传递给 setTimeout() 的字符串是在全局上下文中求值的,因此当字符串被求值为代码时,setTimeout() 被调用的上下文中的局部符号将不可用。

    详情可参考MDN官网:

    MDN-setTimeout

    延时比指定值更长的原因

    1. 嵌套超时:
      一旦对 setTimeout 的嵌套调用被安排了 5 次,浏览器将强制执行 4 毫秒的最小超时。
    2. 定时器队列:
      如果页面(或操作系统/浏览器)正忙于其他任务,超时也可能比预期的晚。需要注意的一个重要情况是,在调用 setTimeout() 的线程结束之前,函数或代码片段不能被执行。
    function foo() {console.log("foo 被调用");
    }
    setTimeout(foo, 0);
    console.log("setTimeout 之后");
    

    出现这个结果的原因是,尽管 setTimeout 以 0ms 的延迟来调用函数,但这个任务已经被放入了队列中并且等待下一次执行;并不是立即执行;队列中的等待函数被调用之前,当前代码必须全部运行完毕,因此这里运行结果并非预想的那样。

    最大延时时间

    浏览器内部以 32 位带符号整数存储延时。这就会导致如果一个延时大于 2147483647 毫秒(大约 24.8 天)时就会溢出,导致定时器将会被立即执行。

    兼容市面上所有的浏览器

    2.setInterval

    setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

    参数:

    1. functionRef: 定时器到需要执行的函数逻辑
    2. delay: 延时时间,单位是毫秒,如果不传这个这个 参数,默认是0,这个值有一个最小值就是4ms,如果小于这个值,会被自动设置为4ms,0除外
    3. param1, …, paramN: 此后的参数都是作为定时器所执行的函数的参数传递

    返回:

    1. 定时器的ID,可以用来取消定时器(这个ID本质上是一个非零数值。)

    取消:

    setInterval的取消可以调用全局对象上的clearInterval方法,该方法接收一个参数,就是定时器的ID。

    注意: setTimeout与setInterval的定时器共用同一个ID池,并且clearInterval与clearTimeout两者在技术实现上时互通的,因此两者其实都可以用于取消上述两种定时器的任何一种,但官方标准上建议我们匹配使用,避免代码杂乱无章。

    this指向:
    y与setTimeout类似

    定时器是可以嵌套的;这意味着,setInterval() 的回调中可以嵌入对 setInterval() 的调用以创建另一个定时器,即使第一个定时器还在运行。为了减轻这对性能产生的潜在影响,一旦定时器嵌套超过 5 层深度,浏览器将自动强制设置定时器的最小时间间隔为 4 毫秒。如果尝试将深层嵌套中调用 setInterval() 的延迟设定为小于 4 毫秒的值,其将被固定为 4 毫秒。

    当浏览器标签页处于后台或不活跃状态时,浏览器可能会延迟执行定时器任务,以节省资源。这种情况下,定时器的执行时间可能会比预期的长。

相关文章:

前端基础面试题·第三篇——JavaScript(其三)

1.字符串 (1) 常用方法 1.charAt(index) 返回指定位置的字符,若没找到&#xff0c;则返回空2.charCodeAt(index) 返回指定位置的unicode字符编码,若没找到&#xff0c;则返回空 3.String.concat(str1,str2) 连接多个字符串&#xff0c;并返回新字符串4.String.fromCharCode(co…...

MacBook真的不能打游戏吗?Mac打游戏会损坏电脑吗?苹果电脑怎么玩游戏

MacBook从来都是高端的代名词&#xff0c;超强的性能搭配顶尖的系统&#xff0c;不光处理大型文件时举重若轻&#xff0c;长期使用也不会有明显卡顿。但很多人在需要MacBook一流的生产力同时&#xff0c;也希望能在空闲时体验游戏的乐趣。在大多人的印象里&#xff0c;Mac电脑对…...

安卓逆向(之)真机root(红米手机)

概览&#xff1a; 1, 手机解锁 2, 下载官方系统包&#xff0c;推荐线刷包,取出镜像文件 3, magisk工具修补 官方系统包 4, adb&#xff1a;命令对手机刷 root 5, 完成 6, 小米手机解锁 点击 小米手机解锁OEM官方教程 记得数据线连接手机电脑 工具下载 点击 下载adb(电脑操作…...

关于转行网络安全的一些建议

在当前就业形势下&#xff0c;不少朋友面临转行的困境。网络安全作为一个热门领域&#xff0c;自然也吸引了许多人的目光。本文将就转行网络安全这一话题&#xff0c;提供一些切实可行的建议。 网络安全行业概况 网络安全涵盖了从基础的脚本编写到高级的漏洞研究等多个层面。该…...

(六十五)第 10 章 内部排序(希尔排序)

示例代码 shellSort.h // // 希尔排序实现头文件#ifndef SHELL_SORT_H #define SHELL_SORT_H#include "errorRecord.h"#define NUM 10 #define MAX_SIZE 20#define EQUAL(a, b) ((a) == (b)) #define LESS_THAN(a, b) ((a) < (b)) #define LESS_OR_EQUAL(a, b) ((…...

802.11 中 scrambler的matlab仿真

802.11a和802.11n中的scrambler仿真不可以直接用matlab中的comm.Scrambler函数。因为这个函数实现的是multiplicative scrambling&#xff0c;而802.11a和802.11n中的scrambler使用的是additive scrambling。additive scrambling使用异或操作进行扰码&#xff0c;multiplicativ…...

centos 服务器 多网卡 ip 地址 设置

centos 服务器 多网卡 ip 地址 设置 https://blog.csdn.net/xh_w20/article/details/141574357 cd /etc/sysconfig/network-scripts/ sudo systemctl status network ● network.service - LSB: Bring up/down networkingLoaded: loaded (/etc/rc.d/init.d/network; bad; v…...

什么是大数据、有什么用以及学习内容

目录 1.什么是大数据&#xff1f; 2.大数据有什么用&#xff1f; 2.1商业与营销&#xff1a; 2.2医疗与健康&#xff1a; 2.3金融服务&#xff1a; 2.4政府与公共服务&#xff1a; 2.5交通与物流&#xff1a; 2.6教育与个性化学习&#xff1a; 3.学习大数据需要学习哪…...

ZBrush与Blender雕刻功能哪个更好些?

选择正确的3D软件首先会让你的创作过程更加轻松&#xff0c;尤其是在动画或大片电影制作方面。不同的软件提供不同的功能&#xff0c;并倾向于专注于特定领域&#xff0c;如绘画、动画或雕刻。如果你选择了适合你风格和目标的软件&#xff0c;你可以创作出极具创意的作品。 在…...

软件工程技术专业软件开发综合实训室解决方案

一、行业背景与前景分析 1.1 软件工程技术专业就业前景 近年来&#xff0c;中国的软件行业取得了显著的成就&#xff0c;即便在全球经济受到新冠疫情冲击的情况下&#xff0c;仍保持了强劲的增长势头。据工业和信息化部发布的数据&#xff0c;2021年我国软件和信息技术服务业…...

链动2+1:高效用户留存与增长的商业模式解析

大家好&#xff0c;我是吴军&#xff0c;任职于一家致力于创新的软件开发企业&#xff0c;担任产品经理的职位。今天&#xff0c;我打算深入分析一个历经时间考验且依旧充满活力的商业模式——“链动21”模式&#xff0c;并通过一个具体的案例和相关数据&#xff0c;展示它如何…...

Python 调用手机摄像头

Python 调用手机摄像头 在手机上安装软件 这里以安卓手机作为演示&#xff0c;ISO也是差不多的 软件下载地址 注意&#xff1a;要想在电脑上查看手机摄像头拍摄的内容的在一个局域网里面(没有 WIFI 可以使用 热点 ) 安装完打开IP摄像头服务器 点击分享查看IP 查看局域网的I…...

E5053A 微波下变频器

_XLT新利通_ E5053A 微波下变频器 E5052B SSA 专用的微波下变频器 Keysight E5053A 是一款与 E5052B 信号源分析仪&#xff08;SSA&#xff09;相关的微波下变频器。 如果您需要设计和测试微波或毫米波频率的信号源&#xff0c;E5053A 支持您扩展该分析仪的频率范围。 从…...

记录:uniapp直播的弹幕的样式修改与发送弹幕会自动滚动到底部两个技巧

1、在直播页面的弹幕评论中&#xff0c;我们希望的样式是&#xff1a; 观众名字&#xff1a;评论 而且颜色有所区分&#xff0c;并在同一行显示 2、我们希望在发弹幕的时候可以回自动滚动到自己发的内容那里 一&#xff1a;弹幕样式修改 因为是小白&#xff0c;前端对于样式这…...

【流程设计】JAVA系统集成activiti工作流,流程设计器,在线审批,会签,驳回,流程图查看(实际多套系统运用案例分析)

基于Javavue开发的智能审批系统&#xff0c;低代码平台方案 其他资料&#xff0c;软件资料清单列表部分文档清单&#xff1a;工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求…...

Debezium系列之:大规模应用debezium server采集数据库,从每个Debezium Server中导出JMX采集指标

Debezium系列之:为每个Debezium Server导出JMX采集指标 一、需求背景二、相关技术内容三、仓库下载对应版本的Debezium Server四、设置jmx指标导出内容五、设置采集JMX六、设置数据库采集七、启动Debezium Server八、查看debezium server的jmx采集指标九、插入数据,观察采集十…...

QY-SW 浮子水位计 RS485 LCD显示屏

产品概述 浮子水位计由水位传感器、显示器、传感器支架、浮子、悬索、平衡锤、RS485通信接口等部分组成&#xff0c;是观测水位变化的监测设备&#xff0c;利用浮子跟踪水位升降&#xff0c;以机械方式直接传动记录。使用浮子式水位计需有测井设备(包括进水管)&#xff0c;适合…...

橘子学ES实战操作之管道类型Ingest pipelines的基本使用

简介 我们在使用ES的时候&#xff0c;经常的用法就是把其他数据源比如Mysql的数据灌到ES中。 借用ES的一些功能来提供数据的全文检索以及聚合分析之类的功能。 在这个灌数据的过程中&#xff0c;我们经常会对数据做一些治理&#xff0c;类似ETL的能力。然后把治理后的数据写入…...

VScode:前端开发中的常用快捷键和技巧

1.菜单栏 2.内容相关&#xff1a; 格式化文档 搜索文件名 代码双开对比 右上角选择拆分...

Radmin-同一局域网只需IP就可以控制电脑

Radmin小编十多年前就在用&#xff0c;它是一款非常好用的局域网控制工具&#xff0c;可以完全替代Windows自带的远程桌面&#xff0c;它的安全性和便于操作性都比Windows的远程桌面好用。 Radmin还有一个好处&#xff0c;就是远程别人电脑时&#xff0c;对方那边毫无察觉&…...

【附答案】C/C++ 最常见50道面试题

文章目录 面试题 1&#xff1a;深入探讨变量的声明与定义的区别面试题 2&#xff1a;编写比较“零值”的if语句面试题 3&#xff1a;深入理解sizeof与strlen的差异面试题 4&#xff1a;解析C与C中static关键字的不同用途面试题 5&#xff1a;比较C语言的malloc与C的new面试题 6…...

C++音视频开发笔记目录

目录 &#x1f315;基础知识&#x1f319;详解FFmpeg&#x1f319;播放音视频时发生了什么&#xff1f; & 视频的编解码 & H264是什么&#xff1f; & MP4是什么&#xff1f; &#x1f315;流媒体环境搭建&#x1f319;windows安装FFMpeg&#x1f319;docker一键部署…...

spring项目整合log4j2日志框架(含log4j无法打印出日志的情况,含解决办法)

Spring整合Log4j2的整体流程 Lo 1&#xff09;导入log4j-core依赖 <!--导入日志框架--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <ver…...

Linux网络:应用层协议http/https

认识URL URL是我们平时说的网址 eg&#xff1a;http常见的URL http://user:passwww.example.jp:80/dir/index.htm?uid1#ch1 注意&#xff1a; 服务器地址就是域名&#xff0c;相当于服务器ip地址 像http服务绑定80端口号&#xff0c;https服务绑定443端口。ssh服务端口绑定…...

transforemr网络理解

1.transformer网络中数据的流动过程&#xff1a; 2.transformer中残差的理解&#xff1a; 残差连接&#xff08;Residual Connection&#xff09; 的核心思想就是通过将输入与经过变化的输出相加&#xff0c;来最大限度地保留原始信息。 transforemr中注意力层网络和前馈神经…...

C++插件管理系统

插件加载目录结构 execute plug.exe plugify.dll plugify.pconfig res cpp-lang-module.pmodule example_plugin.pplugin bin cpp-lang-module.dll example_plugin.dll plugify.pconfig { "baseDir&…...

MyBatis 方法重载的陷阱及解决方案

在使用 MyBatis 进行开发时&#xff0c;尤其是使用注解模式&#xff08;如 Select、Insert 等&#xff09;时&#xff0c;开发者常常会遇到这样一个问题&#xff1a;为什么我的方法重载不能正常工作&#xff1f; 即使在 Java 中允许方法名相同但参数不同的重载&#xff0c;MyBa…...

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADCDMA采样时&#xff0c;遇到了一些小坑记录一下&#xff1b; 一、ADCDMA采样时进入死循环&#xff1b; 解决方法&#xff1a;ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高&#xff0c;且增大ADCHAL_ADC_Start_DMA(&ha…...

Python AttributeError: ‘dict_values’ object has no attribute ‘index’

Python AttributeError: ‘dict_values’ object has no attribute ‘index’ 在Python编程中&#xff0c;AttributeError 是一个常见的异常类型&#xff0c;通常发生在尝试访问对象没有的属性或方法时。今天&#xff0c;我们将深入探讨一个具体的 AttributeError&#xff1a;“…...

三丰云免费虚拟主机和免费云服务器评测

三丰云是一家提供免费虚拟主机和免费云服务器的知名服务提供商&#xff0c;深受用户好评。在这篇评测文章中&#xff0c;我们将对三丰云的免费虚拟主机和免费云服务器进行细致评测。 首先&#xff0c;我们来看看三丰云的免费虚拟主机服务。三丰云的免费虚拟主机提供稳定的服务器…...