js事件面试题大全

以下题目是根据网上多份面经收集而来的,题目相同意味着被问的频率比较高,有问题欢迎留言讨论,喜欢可以点赞关注。

https://www.jianshu.com/p/5f1a8f586019

1、介绍下事件代理,主要解决什么问题,有什么优缺点

①事件代理也叫事件委托,原理:事件冒泡机制
事件委托是利用事件的冒泡原理来实现的,就是事件从最深的节点开始,然后逐步向上传播事件。页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
②解决什么问题:
减少事件注册,在li上注册事件要一百个,用遍历的方法消耗性能,代理代码简单高效
③优缺点
优点:
1.节省内存占用,减少事件注册。比如ul上代理所有li的click事件就很不错。
2.可以实现当新增子对象时,无需再对其进行事件绑定,删除子对象也不需解绑

缺点:
1、事件代理的常用应用应该仅限于上述需求,如果把所有事件都用事件代理,可能会出现事件误判。即本不该被触发的事件被绑定上了事件。比如点击列表中的按钮确进入了详情页面

2、不适应所有的事件,只适用于支持事件冒泡的事件
2、事件循环机制(event loop),node和浏览器的事件循环机制区别

浏览器中的 Event Loop

浏览器端事件循环中的异步队列有两种:macro(宏任务)队列和 micro(微任务)队列。宏任务队列可以有多个,微任务队列只有一个。

  • 常见的 macro-task 比如:setTimeout、setInterval、script(整体代码)、 I/O 操作、UI 渲染等。
  • 常见的 micro-task 比如: new Promise().then(回调)、MutationObserver(html5新特性) 等。
js事件面试题大全_第1张图片
image.png
  • 一开始执行栈空,我们可以把执行栈认为是一个存储函数调用的栈结构,遵循先进后出的原则。micro 队列空,macro 队列里有且只有一个 script 脚本(整体代码)。

  • 全局上下文(script 标签)被推入执行栈,同步代码执行。在执行的过程中,会判断是同步任务还是异步任务,通过对一些接口的调用,可以产生新的 macro-task 与 micro-task,它们会分别被推入各自的任务队列里。同步代码执行完了,script 脚本会被移出 macro 队列,这个过程本质上是队列的 macro-task 的执行和出队的过程。

  • 上一步我们出队的是一个 macro-task,这一步我们处理的是 micro-task。但需要注意的是:当 macro-task 出队时,任务是一个一个执行的;而 micro-task 出队时,任务是一队一队执行的。因此,我们处理 micro 队列这一步,会逐个执行队列中的任务并把它出队,直到队列被清空。

  • 执行渲染操作,更新界面

  • 检查是否存在 Web worker 任务,如果有,则对其进行处理

  • 上述过程循环往复,直到两个队列都清空

区别
浏览器和Node 环境下,microtask 任务队列的执行时机不同

  • Node端,microtask 在事件循环的各个阶段之间执行
  • 浏览器端,microtask 在事件循环的 macrotask 执行完之后执行
3、如何让事件先冒泡后捕获

在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一事件,监听捕获和冒泡,分别对应响应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获事件。

    let w = document.getElementsByClassName('wraper')[0]
    let b = document.getElementsByClassName('buller')[0]
    let i = document.getElementsByClassName('inner')[0]

    // 冒泡阶段
    w.addEventListener('click', function () {
        console.log('capture wraper');
    }, false)
    b.addEventListener('click', function () {
        console.log('capture buller');
    }, false)
    i.addEventListener('click', function () {
        console.log('capture inner');
    }, false)
    // 捕获阶段
    w.addEventListener('click', function () {
        setTimeout(function () {
            console.log('wraper');
        }, 0)
    }, true)
    b.addEventListener('click', function () {
        setTimeout(function () {
            console.log('buller');
        }, 0)
    }, true)

    i.addEventListener('click', function () {
        setTimeout(function () {
            console.log('inner');
        }, 0)
    }, true)
4、说一下浏览器事件,各种父类子类设置冒泡或者捕获,哪个先哪个后
5、使用addEventListener点击li弹出内容,并且动态添加li之后有效
6、刚才你提到了事件流(event loop),能简单的说一下,什么是事件流吗

我们都知道,js是单线程的,虽然现在有 worker 的存在,但是也只是可以进行运算,并不能操作 dom;js最一开始执行的线程,是主线程,然后主线程执行完毕后,是微队列 microtask 的循环执行,微队列执行完毕后,在执行宏队列 macrotask

宏队列的方法setTimeoutsetIntervalsetImmediateI/OUI rendering
微队列的方法promise.thenprocess.nextTickObject.observe(已废弃)

正好之前写过这方面的文章,想详细的理解这一块的知识,跳转:性能优化篇 - js事件循环机制(event loop)

其实,event loop它最主要是分三部分:主线程、宏队列(macrotask)、微队列(microtask)
js的任务队列分为同步任务和异步任务,所有的同步任务都是在主线程里执行的,异步任务可能会在macrotask或者microtask里面

其实,event loop用简单点的话去解释,就是:
1、先执行主线程
2、遇到宏队列(macrotask)放到宏队列(macrotask)
3、遇到微队列(microtask)放到微队列(microtask)
4、主线程执行完毕
5、执行微队列(microtask),微队列(microtask)执行完毕
6、执行一次宏队列(macrotask)中的一个任务,执行完毕
7、执行微队列(microtask),执行完毕
8、依次循环。。。

7、JS运行机制
js事件面试题大全_第2张图片
image.png

https://www.jianshu.com/p/e06e86ef2595

8、线程和进程和区别

javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的,一切javascript多线程都是纸老虎!

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。

一个程序至少一个进程,一个进程至少一个线程。

js事件面试题大全_第3张图片
image.png
js事件面试题大全_第4张图片
image.png
js事件面试题大全_第5张图片
image.png
进程与线程的区别:

1、进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
2、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
3、线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
4、但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
参考:https://www.cnblogs.com/zhehan54/p/6130030.html

9、说说浏览器的事件代理机制的原理

同一

10、简述下浏览器的Event loop

同其他
这一次,彻底弄懂 JavaScript 执行机制

11、浏览器事件流向

DOM事件传播包括三个阶段:
1、捕获阶段
2、目标对象调用事件处理程序
3、冒泡阶段
希望注册在DOM元素上的事件处理程序在捕获阶段还是在冒泡阶段触发,取决于 addEventListener() 方法的第三个参数为 true 还是 false

12、事件冒泡是什么,写一个阻止事件冒泡的js

1.event.stopPropagation(); // 阻止了事件冒泡,但不会阻击默认行为
2.return false; //阻止全部事件
3.event.preventDefault(); //阻止默认事件

13、宏任务(macro-task)微任务(micro-tack)

宏队列的方法setTimeoutsetIntervalsetImmediateI/OUI rendering
微队列的方法promise.thenprocess.nextTickObject.observe(已废弃)

14、setTimeout和setInterva

w3c在HTML标准中规定,要求setTimeout时间低于4ms的都按4ms来算。这里还要注意一点,就是有些时候,为什么一些大神用js做一些类似于动画操作的时候,喜欢用setTimeout,而不是用setInterval呢,因为setTimeout是在这个时间后,把当前的方法推到任务队列里,而setInterval是强行把当前的方法添加到任务队列里,这样可能会对当前页面的用户体验很不好,可能会出现效果卡顿的情况,所以这里还要注意一点:setTimeout是延迟执行,但是不是延迟的时间后立即执行的。


js事件面试题大全_第6张图片
image.png

js事件面试题大全_第7张图片
image.png
15、我们来分析一段较复杂的代码,看看你是否真的掌握了js的执行机制
console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
js事件面试题大全_第8张图片
image.png

js事件面试题大全_第9张图片
image.png
16、target和currentTarget的区别

1、target:触发事件的元素。currentTarget:事件绑定的元素。
2、两者在没有冒泡的情况下,是一样的值,但在用了事件委托的情况下,就不一样了;
例如:

  • fsda
  • ewre
  • qewe
  • xvc
  • 134
js事件面试题大全_第10张图片
image.png

你可能感兴趣的:(js事件面试题大全)