javascript的底层实现学习总结
JavaScript的单线程
Javascript最大的特点就是他的单线程执行,作为浏览器脚本语言,Javascript的主要用途是于用户互动,以及操作DOM,这决定了它只能是单线程,假如javaScript是多线程,一个线程在DOM节点上添加内容,而另一个线程却删除了该节点,这时浏览器因该以哪个线程为准?因此,为了避免复杂性,JavaScript就采用了单线程的工作模式。
JavaScript的结构分析
单线程就意味着它只有一条运行线路,也就是一次只能做一件事情,那么,问题就来了,如果是CPU一直在工作,那也就罢了,但是如果CPU处于空闲状态,而且等待的事务对接下来的任务没有影响,这就浪费了大量的资源。例如:获取网络上的信息,线程一直等到信息获取完成再执行,在此之前都处于等待状态就太浪费了。于是JavaScript就引人了同步异步机制。
同步任务:下一个任务受上一个任务所影响,即需要上一个任务执行完之后才能执行下一个任务。
异步任务:异步任务就是不进入主线程,而进入“任务队列”,(并不是立即执行),等到可以执行了,任务队列会通知主线程:某个异步任务可以执行了。该任务才会被主线程调用执行。(回调函数、定时器函数、用户点击事件等)
运行方式:所有同步任务进入主线程队列执行,所有异步任务进入任务队列,主线程先执行完所有同步任务,再调用可执行的异步任务。(主线程空闲的时候才会调用执行异步任务)。任务队列是一个先进先出的数据结构,排在前面的事件优先被主线程读取。主线程调用时会先检查时间,因为存在定时器函数,这类函数只有满足规定的时间才会被调用。
Event Loop
因为主线程从任务队列中读取事件的这个过程是不断循环的,因此又被称为Event Loop(事件循环)。
Node.js的process.nextTick 和 setImmediate.
process.nextTick=(func) 在当前执行栈的尾部执行。setImmediate(func)在任务队列的尾部。
也就是说nextTick会在当前func执行完成后立即执行func里新加的任务,而setImmediate需要按队列顺序执行到func里增加的任务
JavaScript的call(),bind().apply();
call,bind,apply都是修改对象的this指针。
func.call():修改this指针并执行函数,参数为具体的参数。
func.bind():修改this指针但是不执行函数,返回的是函数名称,参数为具体参数。
func.apply():修改this指针并执行函数,参数为参数数组。
eg: func(para1,para2)
func.call(obj,para1,para2)
func.apply(obj,[para1,para2])