✅最近做了一些题目,整合梳理。解析部分加粗是官方解析,后面是个人理解和知识点的补充,如有错误敬请指出。
第1题
执行以下代码,输出结果是:
setTimeout(function(){
console.log('setTimeout')
},0)
Promise.resolve().then(function(){
console.log('promise1')
}).then(function(){
console.log('promise2')
}
-
A.promise1promise2setTimeout
-
B.promise2promise1setTimeout
-
C.promise2setTimeoutpromise1
-
D.setTimeoutpromise1promise2
答案:A
解析:setTimeout属于宏任务,Promise属于微任务,他们都是异步任务。但是setTimeout需要等待一个时间后再执行,就放在最后输出了。 一般执行顺序是-先执行同步代码,遇到异步宏任务放到宏任务队列中,遇到异步微任务就放到微任务队列中。当所有同步代码执行完毕后,再把微任务调到主线程执行,微任务执行完毕后再将异步宏任务调到主线程执行。
第2题
关于将Promise.all和Promise.race传入空数组的两端代码的输出结果说法正确的是:
Promise.all([]).then((res)=>{
console.log('all')
})
Promise.race([]).then((res)=>{
console.log('race')
})
-
A.all和race都会被输出
-
B.all和race都不会被输出
-
C.all会被输出,race不会被输出
-
D.all不会被输出,race会被输出
答案:C
解析:Promise.all 会立即返回 resolved 状态,因而会立马输出,而 Promise.race 则一直处于 pending 状态,不会走到 then ,所以永远不会输出 promise.all和promise.race的区别在于,promise.all要求所有的Promise对象都成功,而promise.race只要求其中任何一个Promise对象成功或失败。promise.race中传入一个空数组会返回的值是undefined。
第3题
以下代码执行后输出的结果是?
<div id="box1">
<div id="box2">content</div>
</div>
<script>
const $ =document.querySelector.bind(document)
const box1 = $('#box1')
const box2 = $('#box2')
box1.addEventListener('click',0=>{
console.log('box1 true')
},true)
box1.addEventListener('click',0=>{
console.log('box1 false')
},false)
box2.addEventListener('click',0=>{
console.log('box2 true')
},true)
box2.addEventListener('click',0=>{
console.log('box2 false')
},false)
</script>
-
A.box1 true,box2 true,box2 false,box1 false
-
B.box1 true,box2 false,box1 false,box2 true,
-
C.box2 false,box2 true,box1 false,box1 true,
-
D.box1 true,box1 false,box2 true,box2 false,
答案:A
解析:addEventListener的第三个参数规定事件在什么阶段触发,true是在捕获阶段触发,false(默认值)在冒泡阶段触发,由于事件触发是自dom从外向内传播,考虑box1和box2是上下堆叠的玻璃,光传过box1和box2到达后反射回来,光穿过的的顺序为box1 ->box2(捕获结束) -> box2->box1(冒泡结束) 一般事件流的顺序是捕获、触发、冒泡,也可以理解为从外向内的过程是捕获,从内向外的过程是冒泡,触达事件的部分是触发。由于addEventListener第三个参数的规定,先捕获则优先选有box1和true的答案即ABC,而后是box2 true,后面是false的,从里带外,即先box2 后box1。
第4题
执行以下代码,正确的输出结果是
Promise.reject(0).catch(e=>e).catch(e=>console.log(e))
- A.0
- B.Promise对象
- C.undefined
- D无
答案:D
解析:第一个catch执行后返回的已经是一个成功的Promise对象了,所以不会执行第二个catch的回调错误处理只执行最近的一个catch。
第5题(多选)
关于箭头函数,下面说法错误的有哪些
- A.箭头函数没有自己的this,而是会继承上层作用域的this,就像其他普通的变量一样
- B.箭头函数还可以通过.call(),.apply(),.bind()方法来重新绑定它的this值
- C.箭头函数可以像普通函数一样适用arguments对象
- D.多度追求箭头函数的“单行代码”写法可能会降低代码可读性
答案:BC
解析:箭头函数不支持动态改变this值,所以不可以通过.call()、.apply()、.bind()方法来重新绑定它的this值;箭头函数没有arguments对象;箭头函数虽然表面上看是匿名的,但它可以根据前面的变量名和属性名自动推断出同名的name属性 箭头函数不可以被new,也不会像普通函数一样自动拥有prototype属性
这里提到this的指向问题,目前主要有以下几个方面:1-普通函数中this指向的是windo对象;2-被调用的时候,指向调用者;3-构造函数中,指向构造函数的实例对象;4-在call apply中指向第一个参数即被扩展的作用域对象。
在箭头函数中,this的指向是固定的,会绑定定义时所在的作用域,而不是指向运行时所在的作用域。另外,如果箭头函数的外层有普通函数,那么箭头函数的this就会是这个外层普通函数的this。
当对箭头函数使用call或apply方法时,只会传入参数并调用函数,并不会改变箭头函数中this的指向。当对箭头函数使用bind方法时,只会返回一个预设参数的新函数,并不会改变这个新函数的this指向。