当我将变量设置为等于全局变量时,变量指向哪里?

2024-03-23

这是一个简单的例子:

  1| window.gamelogic = {};
  2| var g = gamelogic;
  3| g.points = 1;
  4| g.array = ["foo","bar"];
  5| var b = g.points;
  6| b = b + 1;
  7| console.log(window.gamelogic);
  8| console.log(b);

这将打印:

Object { points=1, array=[2] }
2

所以这里有两点需要注意:

  1. 一个(看似局部的)变量 -g- 当设置为全局时object并更新,还更新全局对象 -窗口游戏逻辑。 (更新中g还更新了窗口游戏逻辑).

  2. A local int, b(设置为全局 int,points),当全局变量改变时,不更新它。 (更新中b没有更新window.gamelogic.points)

基于第一点,人们会认为当 var 指向全局对象时,您实际上只是创建另一个指向该全局对象的同一内存位置的指针。这可以解释为什么更新g还更新窗口游戏逻辑.

然而,b不更新window.gamelogic.points似乎反驳了这一论点。

这里发生了什么?


在 JavaScript 中,变量(和属性)包含values。值可以有许多不同的类型(数字、字符串、布尔值),其中之一是对象引用,这是一个参考一个对象,但不是实际的对象本身。理解对象引用的一个简单方法是,它只是一个数字,就像一个非常大的数组的索引,告诉我们对象在哪里。 (这并不完全正确,但这是一种有用的思考方式。)或者用非编程术语来说,乔可能有一张写着“123 Any St.”的纸。上面写着,那就是乔的家。论文是一个变量(或属性); “123 任何圣”是一个值(在本例中是一个对象引用),而房子是一个对象。

对象不是值,因此它们不能存储在变量或属性中(或作为函数参数传递)。仅有的参考对他们来说可以。

当您为变量或属性赋值(或将其作为参数传递到函数中)时,您copying从源头传入它的值。所以a = b copies的值来自b into a. When b包含一个对象引用,被复制的是引用,而不是对象;然后a and b两者都引用同一个对象。就像玛丽拿出一张纸(a)并抄下乔的纸上的内容(b)。现在两张纸上都写着乔的房子在哪里。这house没有被复制,只是告诉我们它在哪里的信息。

考虑到这一点,让我们看看您的代码。当你这样做时

window.gamelogic = {};

它创建一个对象并将其引用(值)复制到属性中gamelogic。这是此时内存中内容的粗略草图,省略了lot不必要的细节:



                 +-------------------+
                 | (stuff omitted)   |       +-----------+
window:ref429--->| gamelogic: ref758 |------>|           |
                 +-------------------+       +-----------+
  

然后你这样做:

var g = gamelogic;

which (挥手)创建一个变量(稍后我将解释挥手的情况)并分配(复制)value in gamelogic到它。由于该值是对象引用,g and gamelogic现在指向同一个地方;也就是说,他们refer对于同一个对象:



                 +-------------------+
                 | (stuff omitted)   |    
window:ref429--->| gamelogic: ref758 |---+
                 +-------------------+   |   +-----------+
                                         +-->|           |
                                         |   +-----------+
g: ref758--------------------------------+
  

然后你就做

g.points = 1;

它在该对象上创建一个名为points并复制该值1进去:



                 +-------------------+
                 | (stuff omitted)   |    
window:ref429--->| gamelogic: ref758 |---+
                 +-------------------+   |   +-----------+
                                         +-->| points: 1 |
                                         |   +-----------+
g: ref758--------------------------------+
  

让我们强调一下我们在这里所做的事情:我们没有改变g无论如何,它仍然是一样的:对对象的引用gamelogic也参考。我们所做的是改变了状态该对象的(通过向其添加属性)。这是对象的关键之一:它们具有可以更改的状态。当该状态发生更改时,当您查看它时,拥有哪个引用副本并不重要;重要的是。无论如何,您都会看到相同的对象及其(更新的)状态。

好的,继续:

g.array = ["foo","bar"];

它创建一个数组(它是一个对象),并创建一个名为的属性array在我们的对象上,并将数组引用的值复制到属性中:



                 +-------------------+
                 | (stuff omitted)   |    
window:ref429--->| gamelogic: ref758 |---+
                 +-------------------+   |   +---------------+     +----------+
                                         +-->| points: 1     |     | 0: "foo" |
                                         |   | array: ref804 |---->| 1: "bar" |
g: ref758--------------------------------+   +---------------+     +----------+
  

然后你就可以:

var b = g.points;

which (挥手)创建一个变量并复制其中的值g.points (1) 进去:



                 +-------------------+
                 | (stuff omitted)   |    
window:ref429--->| gamelogic: ref758 |---+
                 +-------------------+   |   +---------------+     +----------+
                                         +-->| points: 1     |     | 0: "foo" |
                                         |   | array: ref804 |---->| 1: "bar" |
g: ref758--------------------------------+   +---------------+     +----------+
b: 1
  

Then

b = b + 1;

得到值1 from b, adds 1到它,并存储新值(2) in b. g.points完全不受影响:



                 +-------------------+
                 | (stuff omitted)   |    
window:ref429--->| gamelogic: ref758 |---+
                 +-------------------+   |   +---------------+     +----------+
                                         +-->| points: 1     |     | 0: "foo" |
                                         |   | array: ref804 |---->| 1: "bar" |
g: ref758--------------------------------+   +---------------+     +----------+
b: 2
  

以上要点是:

  • 变量和属性(以及函数参数)包含values.
  • A values具有类型,例如字符串、数字、布尔值或对象引用.
  • An 对象引用只是一个表示对象所在位置的值。
  • 对象不是值;参考对象就是值。
  • 对象具有可以更改的状态。*

(* 如果他们允许的话。可以创建一个不允许其状态改变的对象;这些对象被称为“不可变”对象。并且它可以非常非常方便和强大地做到这一点。在 JavaScript 中,你这样做Object.freeze http://ecma-international.org/ecma-262/5.1/#sec-15.2.3.9类似,因为默认情况下对象非常松散,您只需通过分配即可向它们添加属性。在许多其他语言中,它更基本:您只是不定义任何可以更改的公共字段,并且不定义任何更改对象状态的公共方法。)


关于“创建变量”挥手,我忽略了其中的两个细节,因为它们当时并不重要:

  1. 在 JavaScript 中,var声明是在代码开始运行之前处理的,因此变量g and b两者都在您的分步代码的第一行运行之前就已经创建了。最初, 的值是undefined在他们中。

  2. 因为你用过var在全球范围内,b and g成为全局对象的属性,这就是window指着。实际上,window本身是全局对象的属性。在 ES5 之前,所有全局变量都是全局对象的属性。 (在 ES6/ES2015 中,我们有一个新的全局变量类别:let, const, or class.)

因此从技术上讲,我们的第一个图表应该如下所示:



+--------------------------+
|   +-------------------+  |
|   | (stuff omitted)   |  |
+-->| window: ref429    |--+    +-----------+
    | gamelogic: ref758 |------>|           |
    | g: undefined      |       +-----------+ 
    | b: undefined      |
    +-------------------+
  

……但是,好吧,这似乎没什么用处。 :-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当我将变量设置为等于全局变量时,变量指向哪里? 的相关文章

  • 将构造函数传递给 Array.map?

    我怎样才能做这样的事情 var a 1 2 3 4 a map Date constructor 此代码在 Google V8 上引发错误 SyntaxError Unexpected number 我也尝试过 a map Date con
  • 实现快速 Javascript 搜索?

    基本上 我有一个带有文本框的页面和 ul 列在其下面 这 ul 由用户的朋友列表填充 用户开始在文本框中输入朋友的名字 例如按 r 我想立即更新 ul 每次按键仅显示名字以 R 开头的朋友 例如 Richard Redmond Raheem
  • 计算字符串中的唯一单词

    下面我尝试将字符串数组提供给一个函数 该函数将唯一单词添加到单词数组中 并且如果该单词已经在数组中 则增加计数数组中相应元素的计数 var words var counts calculate a b calculate a c funct
  • 使用 .add() 选择多个 jQuery 对象

    是否 add http api jquery com add 方法允许一次选择多个对象而不是一次添加一个 one add two add three add four on click function 以下变量的设置方式相同 因为每个变量
  • 设置 location.hash 时防止默认行为

    当我这样做时 location hash test url 会更新 页面会定位到具有该 id 的元素 有没有办法阻止页面定位到该元素 Solution 您无法阻止这种行为 但您可以通过暂时隐藏目标来愚弄它 例如 像这样 与 jQuery 无
  • 如何使用 jQuery 在按下按钮后保持按钮处于活动状态

    我见过一些非常相似的问题 但一直无法找到我正在寻找的答案 我已经确定了解决方法 但想知道执行该任务的正确方法 我想要的是单击按钮并使活动状态保持不变 下一次单击将切换状态 这是所需的 我真正需要知道的是如何解决 uiButton activ
  • 当标题中包含“&”时,电子邮件标题无法正确显示,如何在 JavaScript 中修复?

    我有一些代码以以下格式显示文章标题列表 简短描述和作者姓名 标题 作者姓名 描述 作者的姓名和描述与此处无关 因为它们始终显示正确 大多数标题也可以正确显示 以下是一些虚构的示例 关于银行业务您需要了解的最重要的一件事 作者姓名 正确显示
  • 如何以 Rails 方式处理 JavaScript 事件(例如“link_to :remote”)?

    我正在使用 Ruby on Rails 4 我想以 Rails 方式处理 JavaScript 事件 也就是说 例如 假设我有以下内容 link to destroy article path article method gt delet
  • Excel 宏与 Javascript

    我希望使用 Javascript 中的宏而不是默认的 VBA 来操作 Excel 电子表格 我可以使用以下 VBA 代码执行 javascript 代码 javascript to execute Dim b As String b fun
  • 所有事件的 HTML5 EventSource 监听器?

    我使用 EventSource 在 JavaScript 客户端应用程序中推送通知 我可以像这样附加事件监听器 source addEventListener my custom event type function e console
  • 如何翻转 Twitter Bootstrap 的工具提示

    我正在使用 Twitter 的 Bootstrap 来实现工具提示 目前 工具提示显示在链接上方 我希望工具提示出现在链接下方 我该怎么做呢 我正在触发工具提示 它明确指出 底部 但它不想为我工作 tooltip tooltip place
  • 是否可以进行条件解构或有后备?

    我有一个具有许多深层嵌套属性的对象 我希望能够访问 MY KEY 上的属性 如下 但如果该属性不存在 则获取 MY OTHER KEY 我怎样才能做到这一点 const X Y MY KEY Values segments segment
  • 如何在 HTML 表格上使用分页?

    我正在尝试使用这个分页library http flaviusmatis github io simplePagination js 在我的 HTML 表格页面 特别是浅色主题 中 但不知何故 我无法理解如何在我的 HTML 页面中以这种方
  • 将事件添加到 Google Maps API InfoWindow 内的元素

    我想在 Google Maps API v3 InfoWindow 内放置一个带有输入字段和提交按钮的表单 提交后 我想调用一个函数 该函数使用输入字段中输入的地址启动方向服务 这是我的代码 我目前只测试方向事件是否被触发 我已经编写了完整
  • 修剪日期格式 PrimeNG 日历 - 删除时间戳、角度反应形式

    我将以下内容推入我的反应形式 obj 中2016 01 01T00 00 00 000Z但我想要以下2016 01 01 有谁知道有一个内置函数可以实现上述目的 我已经搜索过文档here https www primefaces org p
  • Next.js:如何将 source-map-explorer 与 Next.js 一起使用

    我想分析我的 Next js 构建源地图浏览器 https www npmjs com package source map explorer 有人可以帮我编写脚本吗 对于 React CRA 我使用以下脚本 build analyze n
  • Browserify:如果需要,使用 module.exports,否则暴露全局

    我正在考虑采用浏览器化 http browserify org 对于我的一些项目 但想确保其他人如果想使用 捆绑的 代码就不必使用 browserify 执行此操作的明显方法是通过以下方式公开模块导出module exports以及通过一个
  • 在移动网站中处理 iPhone 事件(如向左滑动)

    iPhone 浏览器是否有可以使用 Javascript 挂钩的特殊事件 例如 如果用户向左滑动 我想执行某个操作 如果有类似的活动 很高兴看到所有这些活动的参考 理想情况下 有一天所有触摸屏移动浏览器都会有一个标准 您可以访问多点触控事件
  • Onblur 事件在另一个 div 的 onclick 之前触发

    如上所述 我有一个按钮 单击该按钮将打开子菜单 对于子菜单中的每个选项 都有三个元素 我认为实际上还有更多元素 但为了简单起见 将其保留为 3 我将焦点放在子菜单的主 div 白色 框架 上 Onblur 这个 div 然后我隐藏子菜单 这
  • 什么是 TinyMCE jQuery 包?

    我被要求在项目中使用 TinyMCE 编辑器 在下载页面上 有一个主包 然后是一个 jQuery 包 This package contains special jQuery build of TinyMCE and a jQuery in

随机推荐