iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >深入理解JavaScript 变量对象
  • 162
分享到

深入理解JavaScript 变量对象

2024-04-02 19:04:59 162人浏览 八月长安
摘要

目录前言变量对象全局上下文中变量对象函数上下文中的变量对象执行过程预编译代码执行总结练习题前言 在上节《深入 javascript 执行上下文栈——WEB 前

前言

在上节《深入 javascript 执行上下文栈——WEB 前端进阶系列第三节》我们讲到,JavaScript 引擎执行一段可执行代码时,会创建对应的执行上下文。

对于每个执行上下文,都有三个重要属性:

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

今天我们来重点讲解变量对象。

变量对象

变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。

执行上下文分为两种:全局上下文和函数上下文,接下来我们来分别讲解这两种上下文的变量对象。

全局上下文中变量对象

全局上下文中的变量对象是全局对象。

下面我们来了解一下全局对象,在 W3school 中的介绍有:

  • 全局对象是预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他预定义的对象、函数和属性。

  • 在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。全局对象在作用域链最底端,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。

  • 由于全局对象在作用域链最底端,这也意味着在顶层 JavaScript 代码中声明的变量都将成为全局对象的属性。

字面上大家理解起来可能比较抽象,接下来我们结合具体例子作进一步讲解。

  • 在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。在浏览器 JavaScript 中,全局对象是 window。在 node.js 中,全局对象是 global。
console.log(this); // window
console.log(this === window); // true
  • 全局对象是 JavaScript 的全局函数和全局属性的占位符。在顶层 JavaScript 代码中声明的变量都将成为全局对象的属性。
// 声明的变量成为了全局对象的属性
var a = 1;
console.log(this.a); // 1

// 声明的函数成为了全局对象的属性
function b() {}
console.log(this.b); // function b
  • 通过使用全局对象,可以访问全局函数和全局属性,也可以访问所有其他预定义的对象、函数和属性。
// 使用全局对象访问全局属性 Math,它是一个对象,它拥有 random 方法。
console.log(this.Math.random()); // 打印一个随机数
  • 所有非限定性的变量和函数名都会作为该对象的属性来查询。
// 这里的 Math 是非限定性的函数名
console.log(Math.random()); // 打印一个随机数
  • 全局对象是 Object 构造函数的实例,这也意味着 Object.prototype(原型)上预定义的属性和方法,是可以通过全局对象访问到的。
console.log(this instanceof Object); // true
  • 在浏览器 JavaScript 中,全局对象有 window 属性且指向自身。
console.log(this.window === this); // true

函数上下文中的变量对象

在函数上下文中,我们用活动对象(activation object, AO)来表示变量对象。

活动对象和变量对象其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,不可在 JavaScript 环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫 activation object,而只有被激活的变量对象,也就是活动对象,各种属性和方法才能被访问。

活动对象是在进入函数上下文时被创建的,它有函数的 arguments 属性作为初始化属性。arguments 属性的值就是 Arguments 对象。

执行过程

函数上下文的代码执行过程共分成两个阶段,分别是:预编译和执行。

预编译

  • 创建 AO 对象,寻找形参和变量声明

  • 把形参和变量名作为 AO 对象的属性名,值为 undefined

  • 把实参赋给形参,实参形参相统一

  • 寻找函数声明,值为函数体

我们来看个例子:

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

  b = 3;
}

foo(1);

这个函数在预编译完成后,AO 会变为:

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

代码执行

在代码执行阶段,会顺序执行代码。根据代码,修改变量对象的值。

上面的例子当代码执行完,AO 会变为:

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

总结

至此,变量对象的创建过程我们就介绍完了,我们来做个总结:

  • 全局上下文的变量对象初始化是全局对象
  • 函数上下文的变量对象初始化只包括 Arguments 对象
  • 在进入执行上下文时会给变量对象添加形参、变量声明、函数声明等初始的属性值(预编译)
  • 在代码执行阶段,会修改变量对象的属性值

练习题

  • 第一题

来看下面两端代码,分别会打印什么?

function foo() {
  console.log(a);
  a = 1;
}

foo();
function bar() {
  a = 1;
  console.log(a);
}
bar();

第一段会报错:Uncaught ReferenceError: a is not defined。

第二段会打印:1。

因为第一段代码 a 没有变量声明,所以函数执行上下文的 AO 中没有 a 变量的定义,此时 AO 的值是:

AO = {
    arguments: {
        length: 0
    }
}

执行打印时,在函数执行上下文的 AO 中没有找到 a 变量的定义,然后就会去全局上下文中找,发现全局也没有,所以就会报未定义的错。

第二段代码,没有使用 var 关键字声明的变量会成为全局对象的属性,所以执行打印时,会从全局对象找到 a 的值,所以会打印 1。

  • 第二题
console.log(foo);

function foo() {}

var foo = 1;

会打印 foo 函数,而不是 undefined。

因为在预编译的第 4 步,会寻找函数声明,值为函数体,也就是函数声明会覆盖变量声明。

到此这篇关于深入理解JavaScript 变量对象的文章就介绍到这了,更多相关JavaScript 变量对象内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 深入理解JavaScript 变量对象

本文链接: https://www.lsjlt.com/news/149395.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 深入理解JavaScript 变量对象
    目录前言变量对象全局上下文中变量对象函数上下文中的变量对象执行过程预编译代码执行总结练习题前言 在上节《深入 JavaScript 执行上下文栈——Web 前...
    99+
    2022-11-13
  • 深入理解Python变量与常量
    变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。常量是一块只读的内存区域,常量一旦被初始化就不能被改变。...
    99+
    2022-06-04
    常量 变量 Python
  • 深入理解Java对象复制
    目录一、图示二、MapStruct三、framework cglib四、问题一、图示 二、MapStruct pom文件 <dependency>...
    99+
    2022-11-12
  • Python中可变和不可变对象的深入讲解
    目录前置知识 有哪些可变对象,哪些不可变对象? 不可变对象和可变对象的区别? 不可变对象的应用场景 从内存角度出发说下有什么区别? 不可变对象可变对象从代码角度看看区别 不可变对象...
    99+
    2022-11-12
  • 深入理解JavaScript中实例对象和new命令
    目录对象是什么(1)对象是单个实物的抽象(2)对象是一个容器,封装了属性(property)和方法(method)构造函数new命令基本用法new命令的原理new.targetObj...
    99+
    2022-12-22
    js中new实例化过程 js new的过程 js实例对象
  • 深入浅析Java中变量与对象的作用域
    深入浅析Java中变量与对象的作用域?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。大多数程序设计语言都提供了“作用域”(Scope)的概念。对于在作用域里定义的名字,作用域同时...
    99+
    2023-05-31
    java 变量 对象
  • 深入理解python类的实例变量和类变量
    本python是python 3.5版本~!!!class aa:       w = 10       def __init__(self):            self.x = 11            self.y = 12  ...
    99+
    2023-01-31
    变量 实例 python
  • C++中对象&类的深入理解
    什么是对象 任何事物都是一个对象, 也就是传说中的万物皆为对象. 对象的组成: 数据: 描述对象的属性 函数: 描述对象的行为, 根据外界的信息进行相应操作的代码...
    99+
    2022-11-12
  • 这么理解js中变量对象
    这篇文章主要讲解了“这么理解js中变量对象”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“这么理解js中变量对象”吧!变量对象是与执行上下文相关的数据作用域。它是一个与上下文相关的特殊对象,它...
    99+
    2023-06-25
  • JavaScript处理变量命名的参数对象
    问题描述:在开发过程中,遇到一个给对象赋值的问题,参数是通过循环变量的方式进行处理。 js 重要函数 window,eval 1、window 定义全局变量。2、...
    99+
    2022-11-13
  • JavaScript面向对象之深入了解ES6的class
    目录前言1.类的定义2.类的构造函数3.类的实例方法4.类的访问器方法5.类的静态方法6.类的继承6.1.extends关键字6.2.super关键字6.3.继承内置类7.类的混入8...
    99+
    2022-11-13
  • 怎么深入理解Python中的ThreadLocal变量
    怎么深入理解Python中的ThreadLocal变量,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在上篇我们看到了 ThreadLocal ...
    99+
    2022-10-19
  • C语言中bool变量的深入理解
    目录前言bool类型变量的大小bool 值与0比较c语言中bool如何输出总结前言 在一些高级语言当中,为了能够完成更好的逻辑判断,因此就有了bool类型,bool类型的变量值只有t...
    99+
    2022-11-12
  • 深入了解JavaScript中let/var/function的变量提升
    目录前言1. let存在提升2. var/function的变量提升2.1 var的变量提升2.2 function的变量提升3. 总结前言 在我们的印象中,当提到JavaScrip...
    99+
    2022-11-13
  • 深入了解Python中的变量
    目录1 Python变量概述2 Python变量的命名3 Python变量赋值3.1 Python赋值概述3.2 Python变量的基本格式3.3 Python变量的其他赋值格式3....
    99+
    2022-11-12
  • 深入浅出理解PHP原理之变量赋值
    PHP的变量赋值 这个标题估计很多人会不屑一顾,变量赋值?excuse me?我们学开发的第一课就会了好不好。但是,就是这样基础的东西,反而会让很多人蒙圈,比如,值和引用的关系。今天...
    99+
    2022-11-12
  • 深入理解Python中变量赋值的问题
    前言 在Python中变量名规则与其他大多数高级语言一样,都是受C语言影响的,另外变量名是大小写敏感的。 Python是动态类型语言,也就是说不需要预先声明变量类型,变量的类型和值在赋值那一刻被初始化,下面...
    99+
    2022-06-04
    赋值 变量 Python
  • Javascript变量函数声明提升深刻理解
    目录前言:变量提升函数提升为什么要提升?最佳实践总结前言: Javascript变量函数声明提升(Hoisting)是在 Javascript 中执行上下文工作方式的一种认识(也可以...
    99+
    2022-11-13
  • 深入讲解Java的对象头与对象组成
    目录一,对象头1,Mark Word2,指向类的指针3,数组长度二,实例数据三,对齐填充字节总结Java对象保存在内存中时,由以下三部分组成: 1,对象头 2,实例数据 3,对齐填充...
    99+
    2022-11-13
  • JavaScript中变量对象的示例分析
    这篇文章主要介绍JavaScript中变量对象的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、变量对象在函数上下文中,我们用活动对象(activation object, AO)来表示变量对象。活动对象和...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作