重学javascript之变量对象

259 阅读4分钟

前言

上一篇:重学javascript之执行上下文栈 juejin.cn/post/695048…

每个执行上下文都有三个重要的属性:

  • 变量对象
  • 作用域链
  • this 本章讲解:深入分析javascript之变量对象

不忘初心,牢记使命

很多同学看到这里的时候可能会认为:“js基础太简单啦,有必要写吗?“的确,相对于初学js的我们,现在回顾是很简单,但是自然界有一个规律的,也包括我们学习前端知识,那就是掌握真理,返璞归真,才能在走向升华的路上愈发坚实!

正文

什么是变量对象

  • 变量对象是执行上下文中的数据作用域, 存储了我们在上下文中定义的变量函数声明
  • 当然不同的执行上下文中的变量对象也是不同的。
  • 我们经常接触的一般就是全局上下文和函数上下文。 接下来我们聊一下全局上下文。

全局上下文

什么是全局对象呢?我们来看一下W3C中的定义。

1. 全局属性和全局函数可以用于所有内建地Javascript对象

全局对象

  • 全局对象是预定义的对象,作为javascript的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。全局对象不是任何对象的属性,所以它每没有名称。
  • 在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。但通常不必用这种方式引用全局对象,因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的 parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript 代码中声明的所有变量都将成为全局对象的属性。
  • JavaScript 代码嵌入一个特殊环境中时,全局对象通常具有环境特定的属性。实际上,ECMAScript 标准没有规定全局对象的类型,JavaScript 的实现或嵌入的 JavaScript 都可以把任意类型的对象作为全局对象,只要该对象定义了这里列出的基本属性和函数。例如,在允许通过 LiveConnect 或相关的技术来脚本化 Java 的 JavaScript 实现中,全局对象被赋予了这里列出的 java 和 Package 属性以及 getClass() 方法。而在客户端 JavaScript 中,全局对象就是 Window 对象,表示允许 JavaScript 代码的 Web 浏览器窗口。

进一步解释:

  1. 可以通过this引用全局对象,在客户端javascript中全局对象就是Window对象

  2. this instanceof Object

  3. Math.random()效果等于 this.Math.random();

  4. var定义的变量挂载到了全局对象上

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

总之: 在全局上下中的变量对象就是全局对象,哈哈哈哈哈!

函数上下文

函数上下文中的变量对象,我们可以称之为活动对象 ( active object )

但是活动对象和变量对象不是一回事,因为活动对象不可以在javascript环境中可以访问,只可以在javascript引擎上实现。也就是当进入到特定的执行上下文中时才可以被激活,只有活动对象被激活才会成为真正的变量对象,那其上的各种属性才能被访问。

执行过程

  1. 进入执行上下文
  2. 执行

进入执行上下文

此时就是一个分析的过程,即并没有执行代码。

变量对象包括:函数形参、函数声明、变量声明

例子

function foo(a) {
  var b = 2;
  function c() {}
  var d = function() {};

  b = 3;

}

foo(1);

进入函数执行上下文

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){},
    d: undefined
}

总结:

  • 全局上下文的变量对象初始化是全局对象

  • 函数上下文的变量对象初始化只包括 Arguments 对象

  • 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值

  • 在代码执行阶段,会再次修改变量对象的属性值