执行上下文(Execution context)
执行上下文可以认为是 代码的执行环境。
1 当代码被载入的时候,js解释器 创建一个 全局的执行上下文。
2 当执行函数时,会创建一个 函数的执行上下文。
3 当执行 eval()的时候,创建 一个 eval 执行上下文。
# if,for,while 等块不会创建 execution context,从而不会创建 scope。
 
当js解释器开始工作的时候:
1 首先创建一个 执行上下文栈(后进先出)
2 接着创建一个 全局的执行上下文,并放入执行上下文栈中。
3 当在全局上下文中调用一个函数的时候.
    为函数创建一个 执行上下文,
    压入执行上下文栈中。
4 当函数执行结束的时候,位于栈顶的 执行上下文 被弹出。继续执行 新的位于栈顶的执行上下文。
 
这种方式保证了 任意时刻都只有位于栈顶的执行上下文才会被执行,也就是实现了单线程。
 
 
执行上下文创建分成两个阶段:
    创建阶段: 将所有的变量,函数声明以及函数参数 组成一个活动对象(可变对象)
    执行阶段: 解释代码.
 
创建阶段具体做的事情:
1 创建 活动对象VO(variableObject)
2 创建 arguments对象
    检测参数,将参数名作为 key值(arguments对象的所有属性都同时是 VO的属性)
3 检测当前执行上下文中的 函数声明 (function fn(){} 这种叫函数声明)
  每检测到一个函数声明都会在 VO 上添加一个属性,属性名就是函数名。属性值就是函数在内存中的引用
  (
      检测到同名依旧覆盖掉。
  )
4 检测变量声明
  每检测到一个变量声明,就在VO上面添加一个属性,属性名就是变量名,属性值就是 undefined.
  (
      检测到同名就丢弃掉当前。
  )
#34的执行顺序没有关系的,调换顺序也是同样的结果。只要变量声明遇见函数声明,最后留下来的肯定是函数声明。
5 确定当前的this的指向。
 
执行阶段:一行一行解释代码.
 
但是在执行阶段还有一个规律:对于同一个变量的赋值,后面的会覆盖前面的。
 
 
假设有函数:
  function foo(i) {
   var a = 'hello';
   var b = function privateB() {
 
   };
   function c() {
 
   }
}
VO大概长这个样子:
ExecutionContext = {
   variableObject: {
       arguments: {
           0: 22,
           length: 1
       },
       i: 22,
       c: pointer to function c()
       a: undefined,
       b: undefined
   },
   scopeChain: { ... },
   this: { ... }
}
 
 
scope chain
js解释器在创建 执行上下文栈 的时候,会同时创建一个 scope chain。一个单向链表.
当 某个执行上下文的创建阶段的最后:创建的活动对象,会被放到 scope chain的 第一个位置。
在执行上下文的 执行阶段的时候,当需要访问某个变量时,
会首先在 当前的 执行上下文的 VO中查找。如果找不到,就往链表的下一个位置查找,一直到最后一个位置。
# 因为链表是单向的,不能反向查找,这也是为什么,全局的执行上下文不能访问 函数上下文的原因,
就是 函数外部访问不了函数内部的原因.
 
 
1 触发 scope chain 查找的原因只有一个:执行上下文的 执行阶段,遇见了当前 VO中不存在的属性。
所以:
    var a = 'outer';
    function test(a){
        console.log(a);//(1)
        var a = 'inner';
        console.log(a);//(2)
    }
    test();
    // output: undefined,'inner'
因为参数是 a>VO 中有 属性 a,在 (1)的时候,a 的值是 undefined,因为存在a,所以不会触发 scope chain 查找.
如果想要触发,把参数 a 改成其他名字.
# 这个东西,帮助理解一下原理就好,不要在代码中这么干,出了问题都不知道哪里有问题。
 
2 这个用来证明scope chain的查找方向。
    var x = 10;
 
    function foo() {
      alert(x);
    }
 
    (function () {
      var x = 20;
      foo();
    })();
 
3 // 重复的函数声明,后面的会覆盖前面的(函数声明比较霸道一点)
function f(){
    console.log(1);
}
 
f();
function f(){
    console.log(2);
}
f();
 
4 执行阶段的时候的规律,后面的赋值会覆盖前面的同名。
var x = 0;
var f = function(){
    x = 1;
}
f();
alert(x);
function f(){
    x = 10;
}
f();
alert(x);
// output: 1,1
 
 
var b = 10;
(function b(){
  b = 20;
    console.log(b);
})();
// output: function b(){...}
原因:
1 首先进入 全局执行上下文,注册了 b
2 全局执行上下文执行 b = 10
3 进入()();创建的执行上下文,注册了 函数声明 b
4 执行-进入 函数执行上下文
5 注册了b是全局的。
6 输出:
  在函数中找不到,在表达式中找到了,就是 function b(){}
 
如果是:
var b = 10;
(function b(){
  var b = 20;
  console.log(b);
})();
// output:20
 
如果是:
var b = 10;
(function(){
  b = 20;
  console.log(b);
})();
// output:20
 
IIFE和 全局的执行上下文之间还有一层执行上下文,这样才能解释上面的的问题。
 
 
函数表达式&函数声明
    var fn = function(){} // 函数表达式
    function fn(){}  // 函数声明
 
记忆:
vb:使用 var 的 都是 biao 达式
 
区别:
函数声明必须要有函数名,只有函数声明才有 hoisting.
 
 
javascript hositing
变量和函数声明总是会被提升到当前作用域的顶部。
原因:
执行上下文的 创建阶段,创建VO对象的时候就已经检测过所有的 变量声明和函数声明了。
所以这个时候 它们已经存在了。
只不过 变量声明的值始终是undefined.而函数声明的值是一个函数在内存地址中的引用.

Javascript 执行上下文 context&scope的更多相关文章

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

    本文转自:http://blogread.cn/it/article/6178 在这篇文章中,将比较深入地阐述下执行上下文 - Javascript中最基础也是最重要的一个概念.相信读完这篇文章后,你 ...

  2. Javascript的“上下文”(context)

    一:JavaScript中的“上下文“指的是什么 百科中这样定义: 上下文是从英文context翻译过来,指的是一种环境. 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境. ...

  3. JavaScript执行上下文

    变量声明.函数声明为何会提升?js执行时是如何查找变量的?JavaScript中最基本的部分——执行上下文(execution context) 什么是执行上下文? 当JavaScript代码运行,执 ...

  4. javascript执行上下文学习一

    原文: http://web.jobbole.com/84044/ http://blog.csdn.net/github_34514750/article/details/52901781 1.三种 ...

  5. 深入理解JavaScript执行上下文、函数堆栈、提升的概念

    本文内容主要转载自以下两位作者的文章,如有侵权请联系我删除: https://feclub.cn/post/content/ec_ecs_hosting http://blog.csdn.net/hi ...

  6. 再看javascript执行上下文、变量对象

    突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...

  7. 图解Javascript——执行上下文

    什么是执行上下文? 执行上下文(Execution Context)是ECMAScript规范中用来描述 JavaScript 代码执行的抽象概念,规定了当前代码执行的环境(当前执行代码片段中的变量. ...

  8. javascript 执行上下文的理解

    首先,为什么某些函数以及变量在没有被声明以前就可以被使用,javascript引擎内部在执行代码以前到底做了些什么?这里,想信大家都会想到,变量声明提前这个概念: 但是,以下我要讲的是,声明提前的这个 ...

  9. javascript --执行上下文,作用域

    执行上下文 顾名思意就知道他是动态的,只在代码运行的时候产生 作用域 顾名思意就知道它是一个"领域",并且这个"领域"在一开始就规划好, 不会在改, var d ...

随机推荐

  1. <正则吃饺子> :关于mybatis中使用的问题(一)

    在公司项目开始之前,根据springboot .mybatis.Swagger2 整合了一个demo,在测试时候,遇到的问题,简单记录.之前在使用mybatis时候,没有注意到这一点. 1.错误:Th ...

  2. .net之特性(Attribute)

    看了一些关于这方面的文档,自我总结: 特性(Attribute)就是对一个方法或类做的一个额外的属性说明,也就是附加说明 下面是我自己抄的一个实例程序: using System; using Sys ...

  3. 大内存电脑在vbox安装linux报错

    问题描述: 1.机器:Linux主机,特别是主机为大内存,比如: 4G内存的使用pae内核的Ubuntu系统的thinkpad电脑. 2.情况:使用VirtualBox安装Linux系统时,比如:通过 ...

  4. js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结(转)

    js中Math.round.parseInt.Math.floor和Math.ceil小数取整总结 Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数 ...

  5. 项目一:第六天 WebService写接口 和CXF框架

    1 课程计划 1. webService入门(了解) 2. 基于jdk1.7开发webservice服务(了解) 3. Apache CXF框架入门(掌握) 4. 基于CXF框架搭建CRM系统(掌握) ...

  6. R语言:文本(字符串)处理与正则表达式

    R语言:文本(字符串)处理与正则表达式 (2014-03-27 16:40:44) 转载▼ 标签: 教育 分类: R 处理文本是每一种计算机语言都应该具备的功能,但不是每一种语言都侧重于处理文本.R语 ...

  7. Free Style Structure text

    最近用了很多文本配置输入,考虑一个最简单的格式,适合C语言scanf读写数据. 基本数据类型直接使用常用形式. double 直接用小数,对应%f读取. int 直接用十进制整数,对应%d读取. ch ...

  8. java线程基础知识----java线程模型

    转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...

  9. React 从入门到进阶之路(三)

    之前的文章我们介绍了 React 创建组件.JSX 语法.绑定数据和绑定对象.接下来我们将介绍 React 绑定属性( 绑定class  绑定style).引入图片  循环数组渲染数据. 上一篇中我们 ...

  10. qemu-nbd使用教程

    服务端 服务器环境 已经安装过qemu-img的32位ubuntu ubuntu@ubuntu-virtual-machine:~/laboratory$ uname -a Linux ubuntu- ...