搜索
首页web前端js教程简约JavaScript中的变量对象

简约JavaScript中的变量对象

Mar 21, 2021 pm 02:54 PM
javascript

JavaScript内功之变量对象

简约JavaScript中的变量对象

目录

  • 前言
  • 一、变量对象
  • 二、全局变量对象
  • 三、函数变量对象
  • 写在最后

(免费学习推荐:javascript视频教程

前言

JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么?

在上篇《JavaScript中的执行上下文》中我们提到了一部分,当 JavaScript 代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。

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

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

在这里插入图片描述

一、变量对象

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

活动对象和变量对象其实是一个东西

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

这里附上一张貘大对于两者关系的回答:
在这里插入图片描述

我们可以将变量对象的创建过程用代码模拟一下:

1.我们用普通的对象来表示变量对象

var VO = {}; // 变量对象

2.而变量对象是执行上下文的一个属性:

activeContext = {
  VO: {
    // 上下文数据(var, FD, function arguments)
  }};

3.当我们遇到下面的代码时:

var a = 10;function func(x){
    var b = 20;}func(30);

4.对应的变量对象应该是:

// 全局变量对象VO(Global) = {
    a: 10,
    func: reference to function plus(){}}// func函数上下文的变量对象VO(func functionContext) = {
  x: 30,
  b: 20};

因为不同执行上下文下的变量对象稍有不同,所以我们分开来说。

在这里插入图片描述

二、全局变量对象

我们先了解一个概念,叫全局对象。在 W3School 中也有介绍:

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

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

console.log(this); //Window

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

console.log(this instanceof Object); // true

3.预定义了一堆,嗯,一大堆函数和属性。

// 都能生效console.log(Math.random());  //随机数console.log(this.Math.random()); //随机数

4.作为全局变量的宿主(很牛的样子)

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

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

var a = 1;console.log(window.a); // 1this.window.b = 2;console.log(this.b); // 2

而全局上下文中的变量对象就是全局对象!

在这里插入图片描述

三、函数上下文中的变量对象

在函数执行上下文中,VO是不能直接访问的,此时由活动对象(activation object,缩写为AO)扮演VO的角色。

VO(functionContext) === AO

活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性的值是Arguments对象:

AO = {
    arguments: <ArgO>}

Arguments对象是活动对象的一个属性,它包括如下属性:

  1. callee — 指向当前函数的引用
  2. length — 真正传递的参数个数
  3. properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。
  4. properties-indexes内部元素的个数等于arguments.length. properties-indexes 的值和实际传递进来的参数之间是共享的。

我们来看下面代码:

function foo(x, y, z) {
 
  // 声明的函数参数数量arguments (x, y, z)
  alert(foo.length); // 3
 
  // 真正传进来的参数个数(only x, y)
  alert(arguments.length); // 2
 
  // 参数的callee是函数自身
  alert(arguments.callee === foo); // true
 
  // 参数共享
 
  alert(x === arguments[0]); // true
  alert(x); // 10
 
  arguments[0] = 20;
  alert(x); // 20
 
  x = 30;
  alert(arguments[0]); // 30
 
  // 不过,没有传进来的参数z,和参数的第3个索引值是不共享的

  z = 40;
  alert(arguments[2]); // undefined
 
  arguments[2] = 50;
  alert(z); // 40
 }
 foo(10, 20);

3.1 执行过程

执行上下文的代码会分成两个阶段进行处理:分析和执行,我们也可以叫做:

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

3.2 进入执行上下文

当进入执行上下文时,这时候还没有执行代码,

变量对象会包括:

  1. 函数的所有形参 (如果是函数上下文)

    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为 undefined
  2. 函数声明

    • 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
    • 如果变量对象已经存在相同名称的属性,则完全替换这个属性
  3. 变量声明

    • 由名称和对应值(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}

3.3 代码执行

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

还是上面的例子,当代码执行完后,这时候的 AO 是:

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

到这里变量对象的创建过程就介绍完了,让我们简洁的总结我们上述所说:

  1. 全局上下文的变量对象初始化是全局对象;
  2. 函数上下文的变量对象初始化只包括 Arguments 对象;
  3. 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值;
  4. 在代码执行阶段,会再次修改变量对象的属性值;

思考题

最后让我们看几个例子:

1.第一题

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

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

第二段会打印:1

这是因为函数中的 “a” 并没有通过 var 关键字声明,所有不会被存放在 AO 中。

第一段执行 console 的时候, AO 的值是:

AO = {
    arguments: {
        length: 0
    }}

没有 a 的值,然后就会到全局去找,全局也没有,所以会报错。

当第二段执行 console 的时候,全局对象已经被赋予了 a 属性,这时候就可以从全局找到 a 的值,所以会打印 1。

2.第二题

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

会打印函数,而不是 undefined 。

这是因为在进入执行上下文时,首先会处理函数声明,其次会处理变量声明,如果如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。

相关免费学习推荐:javascript(视频)

以上是简约JavaScript中的变量对象的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:CSDN。如有侵权,请联系admin@php.cn删除
JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C和JavaScript:连接解释C和JavaScript:连接解释Apr 23, 2025 am 12:07 AM

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

从网站到应用程序:JavaScript的不同应用从网站到应用程序:JavaScript的不同应用Apr 22, 2025 am 12:02 AM

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python vs. JavaScript:比较用例和应用程序Python vs. JavaScript:比较用例和应用程序Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C/C在JavaScript口译员和编译器中的作用C/C在JavaScript口译员和编译器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器