编译执行

64 阅读2分钟

JS中的两个阶段,编译阶段和执行阶段

编译阶段发生在代码执行之前,主要负责将源代码转换成计算机可以直接执行的机器码或字节码

1.1、词法分析:
  • 将源代码分解成一个个有意义的词汇单元。eg:将 var a = 1; 分解成 vara= 1;
1.2、语法分析:
  • 根据词法单元构建抽象语法树(AST),AST 是一种树状结构,表示代码的语法结构。eg:var a = 1; 会被解析成一个赋值表达式的节点。
1.3、代码生成:
  • 将优化后的代码转换为机器代码(或者字节码),以便在执行阶段被执行,并且声明变量。eg:var a = 1;会声明一个类型为undefined的全局变量 a

执行阶段是代码真正运行的阶段,计算机执行编译阶段生成的机器码或字节码。这个阶段主要包括以下几个步骤:

2.1、加载:
  • 将生成的机器码或字节码加载到内存中。
2.2、初始化:
  • 初始化程序的运行环境,包括分配内存、设置初始状态等。
2.3、执行:
  • 逐行执行代码,进行变量赋值、函数调用等操作。(进行RHS与LHS)
LHS查找:
  • LHS 查找是为了找到一个变量的储存位置,以便将一个值赋给它。 在代码var a = 1;中:

    1. var a; 声明了一个变量 a
    2. a = 1; 进行赋值操作,这里就需要进行 LHS 查找,找到 a 的存储位置,然后将 1 赋值给 a
    RHS查找:
  • RHS 查找是为了获取一个变量的值。 在上述代码中:

    1. var a = 1; 声明并初始化了一个变量 a
    2. console.log(a); 进行引用操作,这里就需要进行 RHS 查找,找到 a 的值,然后将其传递给 console.log 函数。

遍历一个dom 树

function traversal(node) {
    if(!node){
       console.log(node);
       return;
    }
    const stack = Array.from(node);  // 获取的是 HTMLNodes 类数组对象,转成数组
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);
            const children = elem.children || [];
            children.length>0 && stack.push(...children); // 直接进行解构操作
        }
    }
}
function traversal(node) {
    //对node的处理
    if (node && node.nodeType === 1) {
        console.log(node.tagName);
    }
    var i = 0,
        childNodes = node.childNodes,
        item;
    for (; i < childNodes.length; i++) {
        item = childNodes[i];
        if (item.nodeType === 1) {
            //递归先序遍历子节点
            traversal(item);
        }
    }
}