执行上下文对象的原理及使用

执行上下文对象:
在浏览器执行javascript代码之前,浏览器会做一些准备工作(从准备工作这一操作开始,直到对应的这一作用域的所有代码被执行完,这样的一个过程就叫做执行上下文;执行上下文可以被看成一个对象,这个对象
就是用来管理其对应作用域中的各个数据,这些数据就是对象中的属性).

一. 全局作用域中的一些准备工作
    1. 找到标记的全局变量,并为其赋值为undefined;
    2. 给this赋值为window对象
    3. 函数声明,并给函数赋值为整个函数块

二. 函数作用域中的一些准备工作
    1. 找到标记的局部变量,并为其赋值为undefined;
    2. 给this赋值为window对象;
    3. 函数声明,并给函数赋值为整个函数块;
    4. 给参数赋值; (管理参数的数组对象)arguments赋值;
    5. 确定自由变量的取值作用域,并给自由变量赋值;
   
    由上面几点看出: 
    1. 函数被定义的时候,就确定了函数体内部变量的作用域;
    2. 函数每被调用一次,就会产生一个新的执行上下文对象,因为不同的调用会有不同的参数;

三. 全局执行上下文对象的数据内容:
    全局变量如:var a=10 或 函数表达式如:var fn={}     :    声明(默认值为undefined)

函数声明如:function fun() {}    :   给这个函数赋值为整个函数块

this   :    赋值为window对象

四. 局部(函数)执行上下文对象的数据内容:
    全局变量如:var a=10 或 函数表达式如:var fn={}     :    声明(默认值为undefined)

函数声明如:function fun() {}    :   给这个函数赋值为整个函数块

this   :    赋值为window对象
   
    参数   :    赋值(传进来的值)

arguments    :   赋值(参数的值,未传实参时,赋空值)

自由变量的取值作用域   :   找到自由变量的作用域,并赋值

五. 执行上下文栈
    执行全局代码时,会产生一个全局上下文环境(压栈),每调用全局中的一个函数时,又会产生一个函数上下文环境,当函数调用完成时,这个函数上下文环境被销毁(出栈),在重新回到全局上下文环境.处于活动状态的上下文环境始终只有一个,这就是压栈和出栈的过程.
   
    例:  var a = 10;  //进入全局上下文环境
         var fn = function(y){
             var c = 5;
             console.log(y + c);
         };
         var bar = function(x){
             var b = 5;
             fn(x + b); //进入fn函数上下文环境
         };
         bar(10); //进入bar函数上下文环境

解析:
        1. 在执行代码之前,首先创建全局上下文环境,此时各个变量的状态为:
                       全局变量a     undefined
                       全局变量fn    undefined
                       全局变量bar   undefined
                       this         window对象
  
        2. 创建全局上下文环境后,开始从上到下依次执行,当读到bar()这句时,前面的全局上下文环境中的变量都被赋值,此时的状态为:
                       全局变量a     10
                       全局变量fn    function
                       全局变量bar   function
                       this         window对象

3. 调用bar函数时(即读bar(10)这条语句),进入函数内部,在执行函数体内部语句之前,创建一个新的该函数作用域的上下文环境,把这个上下文环境压栈,设置为活动状体,此时的状态为:(bar函数的上下文环境)
                       局部变量b     undefined
                              x     10
                      arguments     [10]
                           this     window对象

4. 创建bar的上下文环境后,开始从上到下依次执行bar内的代码,当读到fn(x+b)时,前面的bar的上下文环境中的变量都被赋值,此时的状态为:
                       局部变量b     5
                              x     10
                      arguments     [10]
                           this     window对象
       
         5. 调用fn()函数时(即读fn(x + b)这条语句),进入函数内部,在执行函数体内部语句之前,创建一个新的该函数作用域的上下文环境,把这个上下文环境压栈,设置为活动状体,此时的状态为:(fn函数的上下文环境)
                       局部变量c     undefined
                              y     15(x+b)
                      arguments     [15]
                           this     window对象

6. 当fn函数的上下文环境执行完后,fn的上下文环境被销毁,删除这个上下文环境的所有数据,也就是出栈;此时重新回到bar函数的上下文环境;
         
         7. 当bar函数的上下文环境执行完后,bar的上下文环境被销毁,删除这个上下文环境的所有数据,也就是出栈;此时重新回到全局作用域的上下文环境,直到所有代码执行完毕.

六. 作用域和执行上下文的关系
    1. 在代码中,除了全局作用域外,每个函数都会创建自己的作用域;
    2. 作用域是在函数被定义的时候就确定的,而不是在调用时被确定的;
    3. 作用域只是一个抽象的概念,其中并没有变量,需要通过作用域对应的上下文环境来获取变量的值;
    4. 在同一个作用域下,每次的调用,都会产生不同的上下文环境,当然就会产生不同的变量的值(即使值一样,所在的内存区域却不一样)
    例: (这个例子没看出哪里体现了上面的第2点)
        var a = 10, b = 20;
        function fn(x){
            var a = 100, c = 300;
            function bar(x){
                var a = 1000, d = 4000;
                console.log(a + " " + d);
            }
            bar(100);
            bar(200);
        }
        fn(10);

七. 自由变量
    1. 概念: 在作用域A中,使用了变量X,但并没有在A作用域中声明(即在其他作用域声明的变量X),对于作用域A来说,X就是一 个自由变量.
    例: var X = 10;
        function fn(){
           console.log(X); //这里的X就是一个自由变量
        }

八. 作用域链(这里用变量X举例来说明)
    1. 先在当前所在的作用域查找变量X,如果有,则获取,如果没有,则向当前作用域的上一级继续查找,如果找到,则获取那一级的值;如果还是没有,一直查找到全局作用域;
    2. 如果继续查找到当前的作用域为全局作用域,却还没有找到时,则表示变量X为定义,结束;
    3. 不是全局作用域,那就是函数作用域.

时间: 2024-11-05 12:35:14

执行上下文对象的原理及使用的相关文章

javascript数据类型(六)--- 函数对象之执行上下文

一.引入 1.1 变量声明提升 通过var定义(声明)的变量, 在定义语句之前就可以访问到,其值为: undefined var a = 3 function fn () { console.log(a) //输出结果为undefined var a = 4 } fn() 1.2 函数声明提升 通过function声明的函数, 在之前就可以直接调用,其值为: 函数定义(对象) console.log(b) //undefined 变量提升 fn2() //可调用 函数提升 // fn3() //

深入理解Javascript之执行上下文(Execution Context)

在这篇文章中,将比较深入地阐述下执行上下文 - Javascript中最基础也是最重要的一个概念.相信读完这篇文章后,你就会明白javascript引擎内部在执行代码以前到底做了些什么,为什么某些函数以及变量在没有被声明以前就可以被使用,以及它们的最终的值是怎样被定义的.什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 - 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码 - 当执行一个函数时,运行函数体中的代码. Eva

JavaScript我学之八善变的this---函数执行上下文

本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 函数执行上下文 当函数运行时,通过this,函数可以获取它运行所需的外界环境的相关信息(比如某变量的值,另一个对象的引用等). this引用的对象会”变的”! 每次对函数的调用都有一个上下文对象,this关键字引用它.如果函数归属于某个对象,则this关键字将引用此对象,它就是本次函数调用的上下文. 1 var obj = { 2 func: function () { 3 console.info("func():this="

对于Javascript 执行上下文的理解

转载无源头地址 在这篇文章中,将比较深入地阐述下执行上下文 – JavaScript中最基础也是最重要的一个概念.相信读完这篇文章后,你就会明白javascript引擎内部在执行代码以前到底做了些什么,为什么某些函数以及变量在没有被声明以前就可以被使用,以及它们的最终的值是怎样被定义的. 什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 – 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码 – 当执行一个函数时,运行函数体

理解Javascript之执行上下文(Execution Context)

1>什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 - 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码 - 当执行一个函数时,运行函数体中的代码. Eval的代码 - 在Eval函数内运行的代码. javascript是一个单线程语言,这意味着在浏览器中同时只能做一件事情.当javascript解释器初始执行代码,它首先默认进入全局上下文.每次调用一个函数将会创建一个新的执行上下文. 每次新创建的一个执行上下文会被添加

深入理解javascript执行上下文(Execution Context)

本文转自:http://blogread.cn/it/article/6178 在这篇文章中,将比较深入地阐述下执行上下文 - Javascript中最基础也是最重要的一个概念.相信读完这篇文章后,你就会明白javascript引擎内部在执行代码以前到底做了些什么,为什么某些函数以及变量在没有被声明以前就可以被使用,以及它们的最终的值是怎样被定义的. 什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 - 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的

执行上下文

上下文的原意是 context, 作用域的原意是scope, 这两个不是一个东西. 每一个函数的调用(function invocation) 都有对应的scope 和context. scope 指的是 函数被调用的时候, 各个变量的作用区域context 指的是 current scope and its enclosing scope. 就是当前scope 和包裹它外面的scope. 如果一个变量在当前scope没找到,那么它会自底向上继续找enclosing scope 直到找到为止.很

函数作用域与执行上下文

1.代码分类:全局代码和函数(局部代码) 代码分为编译(由JS编译器执行)阶段和执行(JS引擎执行)阶段.当代码被编译时,会创建相应的作用域,当代码被执行时,会创建相应的执行 上下文. 2.作用域:是在编译阶段就产生的,一整套函数标识符的访问规则,由函数声明时所在的位置决定. 作用:主要用于隔离变量,不同的作用域中变量名字可以相同 作用域链:多个上下级关系作用域形成的链,由下向上或由内向外.定义了变量的查找规则 3.执行上下文: 1)全局执行上下文:执行全局代码前将window确定为全局执行上下

02_作用域与执行上下文区别

<body> <!-- 1. 区别1 * 全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了.而不是在函数调用时 * 全局执行上下文环境是在全局作用域确定之后, js代码马上执行之前创建 * 函数执行上下文是在调用函数时, 函数体代码执行之前创建 2. 区别2 * 作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化 * 执行上下文是动态的, 调用函数时创建, 函数调用结束时就会自动释放 3. 联系 * 执行上下文(对象)是从属于所在的作用域 * 全局上