执行上下文(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. asp.net mvc Partial OutputCache 在SpaceBuilder中的应用实践

    最近给SpaceBuilder增加OutputCache 时发现了一些问题,贴在这做个备忘,也方便遇到类似问题的朋友查阅. 目前SpaceBuilder表现层使用是asp.net mvc v1.0,使 ...

  2. PHPstorm 常用快捷键操作

    1.ctrl+ N: 查找类 2.ctrl+ shift+ N: 全局搜索文件 ,优先文件名匹配的文件 3.ctrl + G: 定位行,跳转行 4.ctrl + F12: 显示当前页面类的所有方法 / ...

  3. Jumony.Core非常厉害的一个开源项目!

    简单的说,就是解析html文档的,以前发送一个get请求获取一个页面的html文本后,想要获取里面的数据都是使用正则表达式.(非常的苦逼), 现在用这个获取就very easy! 安装的话在Nu Ge ...

  4. 获取显示屏的个数和分辨率 --- 通过使用OpenGL的GLFW库

    获取显示屏的个数和分辨率 - 通过使用OpenGL的GLFW库 程序 #include <iostream> // GLFW #include <GLFW/glfw3.h> i ...

  5. 2、perl模块查询安装否

    1.Perl 中每个包有一个单独的符号表,定义语法为:package mypack; 此语句定义一个名为 mypack 的包,在此后定义的所有变量和子程序的名字都存贮在该包关联的符号表中,直到遇到另一 ...

  6. 10.Ubuntu16搭建蜜罐Cowrie

    一直都想尝试搭建一个蜜罐,因为蜜罐是一款可以对ssh,telnet,http等等协议攻击进行记录,对于输入命令和上传文件均有记录的一款软件. 记录可以设置在日志文件中或者通过配置数据库,导入数据库中方 ...

  7. 【idea-部署web项目】

    IntelliJ IDEA 14.x 与 Tomcat 集成,并运行Web项目 时间 2015-01-17 09:40:06  PHP博客 原文  http://blog.snsgou.com/pos ...

  8. Note: ENDBOX: Scalable Middlebox Functions Using Client-Side Trusted Execution

    ENDBOX enable secure networking by client-Side trusted execution. What ENDBOX is a scalable middlebo ...

  9. GTK+学习笔记(一)

    你将学到什么 如何实现弹出式菜单 菜单简介 菜单(GtkMenu)由菜单项(GtkMenuItem)构成,菜单项可以是任意构件比如按钮.菜单(子菜单) 菜单项的管理 菜单外壳(GtkMenuShell ...

  10. CentOS7 LVM磁盘扩容

    1:创建磁盘分区(注意红色命令部分) [root@hongyin-test- ~]# fdisk /dev/sda Welcome to fdisk (util-linux ). Changes wi ...