js部分代码执行机制

来源:互联网 发布:琅琊榜出口数据 编辑:程序博客网 时间:2024/05/01 23:28

js部分代码执行机制

  • 整体代码执行概况


    JS引擎是按照代码块 ('代码块间相互独立,但变量和方法共享') 来进行预处理和执行的,也就是说预处理的只是执行当前的代码块的声明函数和变量,而对于还未加载的代码块,是没法进行预处理的,这也是边编译边处理的核心所在。


    执行流程:    step 1. 读入第一个代码块。    step 2. 做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到step5。    step 3. 对var变量和function定义做“预编译处理”(永远不会报错的,因为只解析正确的声明)。    step 4. 执行代码段,有错则报错(比如变量未定义)。    step 5. 如果还有下一个代码段,则读入下一个代码段,重复step2。    step6. 结束。

  • js函数执行

    1. 函数声明与函数表达式的区别


          函数表达式:var fun = function(){};    函数声明: function fun(){};、    两者比较大的区别在于在解释器解析代码时,会率先读取函数声明,并使其在执行任何代码之前可用(可以访问)。而函数表达式必须等到解析器执行到它所在的代码行,才会被真正的解析执行。    例: alert(sum(b));         function sum(){            return b *= b;         }    ** 当然,变量声明提前的机制依旧存在,若为 var sum = function(){}; 会报错,sum is not a function; 说明sum已经被定义,但没有赋值,类型为 undefined;

    2. 任务队列: 队列模块基于数据缓存模块和数组实现
      常见情况: 操作DOM,事件循环,定时器。 相关操作: 闭包


      主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。执行栈中的代码(同步任务),总是在读取"任务队列"(异步任务)之前执行。举个例子: for (var i = 0; i < lis.length; i++) {     lis[i].onclick = function(){             console.log(i);        }     };运行结果:i 值一直是 lis.length-1; 因为FOR循环为执行栈中的事件,当开始执行任务队列的事件时,FOR循环已经执行完毕,i 值固定。所以i 一直为 lis.length-1;  当然,我们可以采用闭包来获取,当前的 i 值。    for (var i = 0; i < lis.length; i++) {        lis[i].onclick = function(num){                 return function(){                    console.log(num);                }             }(i);    }运行结果: i 值为当前被点击的 li 相对应的 i 值。


    回调函数:
    所谓”回调函数”(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。例: ajax的callback。


3 同步与异步的执行概况
*
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个”任务队列”(task queue)。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。
(3)一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
*

0 0
原创粉丝点击