最近跳槽季,刷面试,被问到的问题,答不出或觉得答的不好,底下查找资料学习下,顺便整理一下,跟大家一起学习!
一、event loop事件循环及线程问题
其实两者是有关联的。就因为JS是单线程,所以所有的任务就得排队执行,js代码始终在一个线程上执行,此线程被称为js引擎线程。(为什么单线程,举别人举的例子:假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?),前一个任务结束,才会执行后一个任务。
说到任务,也分同步和异步任务。所有的同步任务在主线程排队执行,形成一个执行栈。异步任务会被主线程挂起,不会进入主线程,而是进入消息队列,也叫任务队列或事件队列。队列都是先进先出,最先进入的任务最先执行。同时,异步任务需要指定回调函数,一个异步过程包括两个要素:注册函数和回调函数,其中注册函数用来发起异步过程,回调函数用来处理结果。
js是单线程而浏览器是多线程
一下一张来自网上的图,大致有以下线程
1、ui渲染线程主要用来渲染页面。(js可以操作dom,影响渲染,所以js引擎线程和UI线程是互斥的。js执行时会阻塞页面的渲染。)
2、js引擎线程,即上面说的单线程
异步任务需要浏览器执行事件触发线程或定时器触发线程或http请求线程,所以异步是浏览器的两个或者两个以上线程共同完成的。
了解了以上,我们来说下event loop事件循环
详细步骤如下:
1、所有同步任务都在主线程上执行,形成一个执行栈
2、主线程之外,还存在一个"消息队列"。只要异步操作执行完成,就到消息队列中排队
3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取消息队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
4、主线程不断重复上面的第三步
由于主线程不断的重复获得消息、执行消息、再取消息、再执行。所以,这种机制被称为事件循环
实例说明:
console.log(1) div.onclick = () => {console.log('click')} console.log(2) setTimeout(() => {console.log('timeout')},1000)
1、执行第一行代码,第一行是一个同步任务,控制台显示1
2、执行第二行代码,第二行是一个异步任务,发起异步请求,可以在任意时刻执行鼠标点击的异步操作
3、执行第三行代码,第三行是一个同步任务,控制台显示2
4、执行第四行代码,第四行是一个异步任务,发起异步请求,1s后执行定时器任务
5、假设从执行第四行代码的1s内,执行了鼠标点击,则鼠标任务在消息队列中排到首位
6、从执行第四行代码1s后,定时器任务到消息队列中排到第二位
7、现在同步任务已经执行完毕,则从消息队列中按照次序把异步任务放到执行栈中执行
8、则控制台依次显示'click‘、'timeout'
9、过了一段时间后,又执行了一次鼠标点击,由于消息队列中已经空了,则鼠标任务在消息队列中排到首位
10、同步任务执行完毕后,再从消息队列中按照次序把异步任务放到执行栈中执行
11、 则控制台显示'click'
二、this指向问题
this 指的是当前对象,如果在全局范围内使用this,则指代当前页面window;如果在函数中使用this,则this指代什么是根据当前函数是在什么对象上调用。函数中的this是在运行时候决定的,而不是函数定义时。可以使用call和apply改变函数中this的具体指向。
function dog(){ console.log(this.name); } var name = "哈士奇"; dog(); //哈士奇 var o = { name: "金毛" }; dog.call(o); //金毛
三、浏览器内核
浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。通常最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。常见的浏览器内核有:Trident(IE内核)、Gecko(Firefox 内核)、谷歌Blink内核、weblit内核
四、margin-top/top的百分比是相对于父元素的宽度计算的。
五、弹性布局的了解
六、闭包