JavaScript 执行过程



JavaScript整个执行过程,分为两个阶段,代码编译阶段和代码执行阶段node

  1. 1、编译阶段

编译阶段由编译器执行,将代码翻译成可执行代码,这个阶段肯定做用域规则。数组

变量的预编译只做声明,不做初始化,初始化在执行时浏览器

function语句定义的函数,不只声明了函数名,并且函数体也进行了处理bash


2、执行阶段函数

执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段建立。执行上下文也分为建立阶段和执行阶段。ui

一、执行上下文this

执行上下文能够理解为当前代码的执行环境,它会造成一个做用域。spa

二、三种类型翻译

a、全局执行上下文:浏览器的全局对象是window对象,this指向这个全局对象code

b、函数执行上下文:存在无数个,只有在函数被调用的时候才会被建立,每次调用函数都会建立一个新的执行上下文,函数上下文的变量对象初始化只包括 Arguments 对象。

c、Eval函数执行上下文:指运行在eval函数的代码,不多用并且不建议使用。。

建立阶段:

肯定this的值,也被成为 This Binding;

This Binding

a、全局执行上下文中,this 指向全局对象,在浏览器中this 指向window对象,在nodejs中指向这个文件的module 对象。

b、函数执行上下文中,this的值取决于函数的调用方式。具体有:默认绑定、隐式绑定、显式绑定、new绑定、箭头函数。

例一:变量提高

foo();  // 报错  
var foo = function () {
    console.log('foo1');
}

foo();  // foo1,foo从新赋值

var foo = function () {
    console.log('foo2');
}

foo(); // foo2,foo从新赋值
复制代码

例二:函数提高

foo();  // foo2
function foo() {
    console.log('foo1');
}

foo();  // foo2

function foo() {
    console.log('foo2');
}

foo(); // foo2
复制代码

例三:声明优先级,函数 > 变量

foo();  // foo2
var foo = function() {
    console.log('foo1');
}

foo();  // foo1,foo从新赋值

function foo() {
    console.log('foo2');
}

foo(); // foo1
复制代码

须要注意的是同一做用域下存在多个同名函数声明,后面的会替换前面的函数声明。


3、执行上下文栈

由于JS引擎建立了不少的执行上下文,因此JS引擎建立了执行上下文(Execution context stack,ECS)来管理执行上下文。

当 JavaScript 初始化的时候会向执行上下文栈压入一个全局执行上下文,咱们用 globalContext 表示它,而且只有当整个应用程序结束的时候,执行栈才会被清空,因此程序结束以前, 执行栈最底部永远有个 globalContext。

ECStack = [        // 使用数组模拟栈
    globalContext
];复制代码

当执行一个函数的时候,就会建立一个执行上下文,而且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。

var scope = "global scope";
function checkscope(){
    var scope = "local scope1";
    function f(){
        console.log(scope);
    }
    return f(); //执行
}
checkscope(); 


var scope = "global scope";
function checkscope(){
    var scope = "local scope22";
    function f(){
        console.log(scope);
    }
    return f; //返回function
}
checkscope()();复制代码

第一段代码:

ECStack.push(<checkscope> functionContext);//执行checkscope
ECStack.push(<f> functionContext);//执行f
ECStack.pop();//弹出f
ECStack.pop();//弹窗checkscope复制代码

第二段代码:

ECStack.push(<checkscope> functionContext);//执行checkscope
ECStack.pop();//返回function
ECStack.push(<f> functionContext);//执行f
ECStack.pop();//返回f复制代码
相关文章
相关标签/搜索