执行上下文(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. hadoop mapreduce 计算平均气温的代码,绝对原创

    1901 46 1902 21 1903 48 1904 33 1905 43 1906 47 1907 31 1908 28 1909 26 1910 35 1911 30 1912 16 1913 ...

  2. MySql数据库数据更新操作其高级应用

    数据更新操作有3种:向表中添加数据.修改表中的数据和删除表中的数据. 用来演示的数据表用student.course.sc三个数据表,数据表具体内容在:PHP和MySql数据库,如何获取每个分类的记录 ...

  3. hadoop2.6.0完全分布式部署

    这里是hadoop最小的配置,也就是修改最少量的东西让hadoop跑起来. 系统是 Centos6.7 64位, hadoop是2.6.0,虚拟机是VMWare WorkStation 假设虚拟机启动 ...

  4. 在64位ubuntu上安装alienbrain客户端

    一.首先从Alienbrain_EN_10.5.zip安装包(网上可搜索下载)里提取出linux版安装文件:Installations/Clients/Linux/NoVM/install.bin并c ...

  5. R: which(查询位置)、%in% (是否存在)、ifelse(判断是否):

    ################################################### 问题:ifelse.which.%in%    18.4.27 解决方案: > x < ...

  6. 第 2 章 Python 语言入⻔

    目录 2.1低而长的学习曲线 2.2Python的优势 2.3在你的计算机中安装Python 2.4如何运行Python程序 2.5文本编辑器 2.6寻求帮助 Python语言是一种流行的编程语言,在 ...

  7. HDU 5971 Wrestling Match (二分图)

    题意:给定n个人的两两比赛,每个人要么是good 要么是bad,现在问你能不能唯一确定并且是合理的. 析:其实就是一个二分图染色,如果产生矛盾了就是不能,否则就是可以的. 代码如下: #pragma ...

  8. php获取request_uri

    urlParameters = http_build_query( filter_input_array( INPUT_GET, FILTER_SANITIZE_URL ) ); $_request_ ...

  9. 微信小程地图片未加载成功的情况 Failed to load local image resource

    在开发小程序的时候,发现在加载图片时并没有异常,但是后台却报错了. 例如以下我的一段代码: <view class="useage2 "> <image src= ...

  10. Java中Method.invoke方法,反射?

    正常来说,我们调用对象的方法是通过dot运算符来进行的,这里我们介绍另一种方法,有以下几个步骤:1,获取该类的Class Type:2,通过getMethod方法获取Method对象:3,通过调用in ...