因创造执行环境分为三个级次,会创设对应的实施上下文(execution

变量对象

在《javascript
之实践环境-08》文中说到,当JavaScript代码执行一段可实施代码时,会创制对应的实行上下文(execution
context)。对于各类执行上下文,都有三个首要性质:

  • 变量对象(Variable object,VO)
  • 功能域链(Scope chain)
  • this 

各种执行环境(执行上下文)都有二个一点青眼的变量对象(variable
object),环境中形参、函数、定义的享有变量都保留在变量对象中。

变量对象

在《javascript
之实践环境-08》文中说到,当JavaScript代码执行一段可进行代码时,会成立对应的进行上下文(execution
context)。对于各样执行上下文,都有四个第2性质:

  • 变量对象(Variable object,VO)
  • 效益域链(Scope chain)
  • this 

各种执行环境(执行上下文)都有贰个应和的变量对象(variable
object),环境中形参、函数、定义的富有变量都保存在变量对象中。

创制变量对象进程

因创制执行环境分为八个级次,所以变量对象也分七个等级来分析:

  1. 初步化(当函数被调用,未履行代码在此之前)
  2. 代码执行阶段(起初推行代码)

成立变量对象进程

因成立执行环境分为三个等级,所以变量对象也分多少个级次来分析:

  1. 开始化(当函数被调用,未执行代码此前)
  2. 代码执行阶段(伊始实施代码)

初始化

VO包括:

① 、依照函数的参数,创造并开始化arguments object,值为暗中同意值
undefined

二 、扫描该实施上下文中的函数注脚(不包含函数表明式)

      a)  找到全体的function
注解,将函数名当做属性创设,值为函数定义

      b)
 在扫描进程中一经存在重名的函数注明,那么前面包车型客车会覆盖前边的扬言,函数注解与变量注解有顶牛时,会忽视(以函数注解为主)

③ 、 扫描该执行上下文中的var变量申明

      a)
 找到全数的变量注脚,将变量名当做属性创立,值早先为undefined

      b)  在扫描进程中只要存在重名的变量申明以及重名的函数注脚,会忽略;

一般来说代码:

1     function foo(name) {
2         var age = 20;
3         function run() {}
4         var say = function() {};
5         age = 22;
6     }
7     foo('Joel');

创制执行环境时初阶化的变量对象(vo)如下:

 1 foo.EC.VO = {
 2     arguments: {
 3         0: 'Joel',
 4         length: 1
 5     },
 6     name: 'Joel',//参数
 7     age: undefined,
 8     run: reference to function run(){},
 9     say: undefined    
10 }

初始化

VO包括:

① 、依据函数的参数,创设并早先化arguments object,值为暗许值
undefined

② 、扫描该实施上下文中的函数证明(不包罗函数表明式)

      a)  找到全部的function
评释,将函数名当做属性创制,值为函数定义

      b)
 在围观进程中一经存在重名的函数注解,那么后边的会覆盖后边的宣示,函数评释与变量评释有争辩时,会忽略(以函数注明为主)

③ 、 扫描该实施上下文中的var变量申明

      a)
 找到全体的变量表明,将变量名当做属性创造,值初叶为undefined

      b)  在扫描进程中一经存在重名的变量证明以及重名的函数评释,会忽略;

正如代码:

1     function foo(name) {
2         var age = 20;
3         function run() {}
4         var say = function() {};
5         age = 22;
6     }
7     foo('Joel');

创造执行环境时早先化的变量对象(vo)如下:

 1 foo.EC.VO = {
 2     arguments: {
 3         0: 'Joel',
 4         length: 1
 5     },
 6     name: 'Joel',//参数
 7     age: undefined,
 8     run: reference to function run(){},
 9     say: undefined    
10 }

举办阶段

在代码执行阶段,会相继执行代码,依据代码执行顺序,修改AO(执行阶段执行环境被推入执行环境栈
VO 被激活成为AO)中变量的值  如:

 1 foo.EC.VO = {
 2       arguments: {
 3           0: 'Joel',
 4           length: 1
 5       },
 6       name: 'Joel',//形参
 7       age: 20,
 8       run: reference to function run(){},
 9       say: reference to FunctionExpression say
10  }

推行阶段

在代码执行阶段,会相继执行代码,依据代码执行顺序,修改AO(执行阶段执行环境被推入执行环境栈
VO 被激活成为AO)中变量的值  如:

 1 foo.EC.VO = {
 2       arguments: {
 3           0: 'Joel',
 4           length: 1
 5       },
 6       name: 'Joel',//形参
 7       age: 20,
 8       run: reference to function run(){},
 9       say: reference to FunctionExpression say
10  }

透过VO创设进度来看变量进步(Hoisting)

变量进步的精神正是函数在创造执行环境时变量对象伊始化下了形参、函数表明、var
评释的变量;

 1 <script>
 2   function run(){
 3       console.log(name);
 4       console.log(say);
 5       var name='Joel';
 6       function say(){
 7           console.log('say');
 8       }
 9   }
10     run();
11 </script>

 

图片 1

如上代码能够明白为如此:

 1   function run(){
 2     function say(){  //Hoisting
 3           console.log('say'); 
 4       }
 5      var name=undefined; //Hoisting
 6 
 7       console.log(name);
 8       console.log(say);
 9       name='Joel';
10       
11   }
12     run();

经过VO创立进程来看变量提高(Hoisting)

变量进步的本色正是函数在开立执行环境时变量对象最先化下了形参、函数评释、var
注解的变量;

 1 <script>
 2   function run(){
 3       console.log(name);
 4       console.log(say);
 5       var name='Joel';
 6       function say(){
 7           console.log('say');
 8       }
 9   }
10     run();
11 </script>

 

图片 2

如上代码可以知道为这么:

 1   function run(){
 2     function say(){  //Hoisting
 3           console.log('say'); 
 4       }
 5      var name=undefined; //Hoisting
 6 
 7       console.log(name);
 8       console.log(say);
 9       name='Joel';
10       
11   }
12     run();

思考题

思考题

第一题

 1 <script>
 2     function run() {
 3         console.log(a);
 4         a = 1;
 5     }
 6     run(); // ?
 7     function say() {
 8         a = 1;
 9         console.log(a);
10     }
11     say(); // ?
12 </script>

先是段会报错:Uncaught ReferenceError: a is not defined。第壹段会打字与印刷:1

1     function foo(name) {
2 
3         console.log(run);// 输出run 函数定义
4         console.log(say); //undefined
5         function run() {}
6         var say = function () {};
7     }
8     foo('Joel');

函数表达式会当做二个var 变量来拍卖

第一题

 1 <script>
 2     function run() {
 3         console.log(a);
 4         a = 1;
 5     }
 6     run(); // ?
 7     function say() {
 8         a = 1;
 9         console.log(a);
10     }
11     say(); // ?
12 </script>

第叁段会报错:Uncaught ReferenceError: a is not defined。第2段会打字与印刷:1

1     function foo(name) {
2 
3         console.log(run);// 输出run 函数定义
4         console.log(say); //undefined
5         function run() {}
6         var say = function () {};
7     }
8     foo('Joel');

函数表达式会当做3个var 变量来拍卖

第二题

1     console.log(run)
2     function run() {
3         console.log(a);
4         a = 1;
5     }
6   var run=1;

输出: ƒ run() {
            console.log(a);
             a = 1;
         }

当证明的变量与函数重名时,注明的变量会忽略;

要是在第六行代码前面添加 console.log(run),那么run
值会被重置为1,因为在上下文对象成立阶段发现早已存在run的函数申明,var
变量会被忽略,当代码在真正执行到6行时run的值被改成了;

1     console.log(run)
2     function run() {
3         console.log(a);
4         a = 1;
5     }
6   var run=1;
7     console.log(run)

图片 3

第二题

1     console.log(run)
2     function run() {
3         console.log(a);
4         a = 1;
5     }
6   var run=1;

输出: ƒ run() {
            console.log(a);
             a = 1;
         }

当注解的变量与函数重名时,表明的变量会忽视;

假若在第伍行代码后边添加 console.log(run),那么run
值会被重置为1,因为在上下文对象创立阶段发现已经存在run的函数注解,var
变量会被忽视,当代码在真的实施到6行时run的值被改变了;

1     console.log(run)
2     function run() {
3         console.log(a);
4         a = 1;
5     }
6   var run=1;
7     console.log(run)

图片 4

大局上下文中的VO

上篇中说到执行环境分为全局执行环境,函数执行环境,在本文开篇说到每一种执行环境对应一个变量对象:

各样执行环境(执行上下文)都有3个对应的变量对象(variable
object),环境中(执行上下文中)定义的有着形参、变量、函数都封存在那么些指标中,那么全局执行环境是还是不是可以知晓为也设有八个全局变量对象。

大家先通晓3个概念,什么叫叫全局对象。在 W3School 中也有介绍:

全局对象是预订义的目的,作为 JavaScript
的全局函数和大局属性的占位符。通过动用全局对象,能够访问具有别的兼具预约义的对象、函数和个性。

在顶层 JavaScript 代码中,可以用关键字 this
引用全局对象。但平日不必用那种方法引用全局对象,因为全局对象是职能域链的头,那象征全部非限定性的变量和函数名都会作为该对象的品质来查询。

譬如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的
parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript
代码中申明的具备变量都将成为全局对象的性质。

1.方可因而 this 引用,在客户端 JavaScript 中,全局对象正是 Window 对象。

console.log(this);

2.全局目的是由 Object 构造函数实例化的四个对象。

console.log(this instanceof Object);

3.预订义了一大堆函数和属性。

// 都生效
console.log(Math.random());
console.log(this.Math.random());

4.看成全局变量的宿主。

var a = 1;
console.log(this.a);

5.客户端 JavaScript 中,全局对象有 window 属性指向本人。

var a = 1;
console.log(window.a);

this.window.b = 2;
console.log(this.b);

写了那样多介绍全局对象,其实便是想说:全局上下文中的变量对象便是window

全局上下文中的VO

上篇中说到实践环境分为全局执行环境,函数执行环境,在本文开篇说到各种执行环境对应七个变量对象:

每一个执行环境(执行上下文)都有一个相应的变量对象(variable
object),环境中(执行上下文中)定义的装有形参、变量、函数都保留在这些指标中,那么全局执行环境是还是不是能够知道为也设有1个全局变量对象。

大家先了然三个概念,什么叫叫全局对象。在 W3School 中也有介绍:

大局对象是预约义的对象,作为 JavaScript
的全局函数和全局属性的占位符。通过行使全局对象,能够访问具有其余具备预约义的靶子、函数和本性。

在顶层 JavaScript 代码中,可以用关键字 this
引用全局对象。但常常不必用那种措施引用全局对象,因为全局对象是意义域链的头,那意味着全部非限定性的变量和函数名都会作为该对象的习性来询问。

例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的
parseInt 属性。全局对象是意义域链的头,还意味着在顶层 JavaScript
代码中扬言的装有变量都将变为全局对象的属性。

1.得以经过 this 引用,在客户端 JavaScript 中,全局对象正是 Window 对象。

console.log(this);

2.全局指标是由 Object 构造函数实例化的三个对象。

console.log(this instanceof Object);

3.预订义了一大堆函数和总体性。

// 都生效
console.log(Math.random());
console.log(this.Math.random());

4.用作全局变量的宿主。

var a = 1;
console.log(this.a);

5.客户端 JavaScript 中,全局对象有 window 属性指向本人。

var a = 1;
console.log(window.a);

this.window.b = 2;
console.log(this.b);

写了如此多介绍全局对象,其实正是想说:全局上下文中的变量对象便是window

一举手一投足对象(AO)与变量对象(VO)不同

它们其实都以同三个目标,只是处在执行上下文的两样生命周期。未进入执行阶段从前,变量对象(VO)中的属性都无法访问,但是进入实践等级之后,执行环境被压入执行环境栈变量对象(VO)转变为了活动对象(AO),里面包车型客车习性都能被访问了,然后起头进行实施等级的操作。

一举手一投足目的(AO)与变量对象(VO)差别

它们其实都是同四个对象,只是处在执行上下文的两样生命周期。未进入执行阶段在此之前,变量对象(VO)中的属性都无法访问,可是进入实施等级之后,执行环境被压入执行环境栈变量对象(VO)转变为了活动对象(AO),里面包车型大巴习性都能被访问了,然后初阶展开实践阶段的操作。

总结

  1. 大局上下文的变量对象是全局对象
  2. 函数上下文的变量对象起头化,最初阶只包蕴 arguments 对象
  3. 在开创执行上下文时会给变量对象添加形参、函数申明、变量表明等最先的属性值
  4. 在代码执行阶段,会另行修改变量对象的属性值
  5. 始建执行环境—-》早先化变量对象(AO)(参数、函数注明、var
    变量)—》执行环境被推入栈—-》执行代码—–》VO 激活为AO
    ——》改变AO 的值

 

总结

  1. 全局上下文的变量对象是大局对象
  2. 函数上下文的变量对象伊始化,最发轫只包括 arguments 对象
  3. 在创造执行上下文时会给变量对象添加形参、函数证明、变量申明等上马的属性值
  4. 在代码执行阶段,会重新修改变量对象的属性值
  5. 制造执行环境—-》开首化变量对象(AO)(参数、函数评释、var
    变量)—》执行环境被推入栈—-》执行代码—–》VO 激活为AO
    ——》改变AO 的值

 

相关文章