繁体   English   中英

导出文件 Scope ES6 变量 Javascript

[英]Exported File Scope Variables of ES6 Javascript

跟进What is file scope in javascript ,从中我知道可能有也可能没有所谓的 File Scope 变量,但是,我确实记得在某处读过这个术语但再也找不到了,除了问答javascript 中的文件 scope 是什么 反正,

我想知道此类导出文件 scope 变量的确切行为定义是什么。

因为我试图动态切换我的机器人但无法做到,一个一个地消除因素,它最终落在我身上是因为这样的“导出文件 scope 变量”,而我不理解它们的行为。 看看下面这个极其简化的机器人应用程序:

VarTestFileA.js

function nextBot() {
  BotC = !BotC
  return BotA[BotC]
}

function logBot() {
  console.log("I:", bot)
}

const BotA = {true: {"token": 2}, false: {"token":3}}
let BotC = true

var bot = BotA[BotC]

module.exports = {
  bot,
  nextBot,
  logBot,
}

VarTestFileB.js

const bt = require('./VarTestFileA')

console.log(bt.bot)

bt.bot = bt.nextBot()
bt.logBot()
console.log("O:", bt.bot)

bt.bot = bt.nextBot()
bt.logBot()
console.log("O:", bt.bot)

bt.bot = bt.nextBot()
bt.logBot()
console.log("O:", bt.bot)

您可能知道(即使没有运行它)无论我怎么做,都无法切换bt.bot 这是 output:

$ node VarTestFileB.js
{ token: 2 }
I: { token: 2 }
O: { token: 3 }
I: { token: 2 }
O: { token: 2 }
I: { token: 2 }
O: { token: 3 }

另外,我尝试从VarTestFileA.js中切换bot ,它在其中工作,但console.log("O:", bt.bot.token)从不显示更新的值。 一切的一切,

这一切都归结为此类导出文件 scope 变量的精确行为定义,因为如果将它们放在同一个文件中,它运行得非常好。 因此问题。

这种行为非常直接,同时也很有趣。 语句const bt = require('./VarTestFileA')创建导出的 object 的 object 副本,我们使用变量(例如bot )的地方 - 传递值而不是引用,但是我们传递Function然后传递引用因为函数是 JS 中的对象。

我们从VarTestFileA.js导出{ bot, nextBot, logBot }所以dt实际上等于:

dt = {
  bot : bot, //copy of old bot = BotA[BotC] which equals {"token": 2} 
  nextBot: nextBot, //reference to nextBot() which has access to bot in file A
  nextBot: logBot , //reference to logBot () which has access to bot in file A
}

现在来到我们打印并尝试理解行为的VarTestFileB.js ,让我们看看每个语句的行为方式:

第一条声明:

console.log(bt.bot)将打印{"token": 2}因为bot是按值而不是引用传递的。

第二个陈述:

bt.bot = bt.nextBot()这实际上改变了dt.bot的值而不是文件 A 中的真实bot 。因此bt.bot将具有切换值,但文件 A 中声明的实际bot仍然相同,因为它没有改变。 现在将我们带到第三个陈述:

第三声明:

bt.logBot() ,这会打印文件 A 中bot的初始值。因为它没有被更改。

所以这里真正的答案是,基于这种行为,我们可以声明,如果我们持有文件 A 中变量的引用,那么我们可以从另一个文件更改它们。 但是我真的可以为此提供证据吗? 嗯,是的,让我们看看下面如何


为了测试这一点,让我们在文件 A 中创建另一个方法;

function getBot(){
    return bot;
}

然后修改nextBot如下:

function nextBot() {
    BotC = !BotC
    bot = BotA[BotC]
}

然后导出对这些方法的引用;

module.exports = {
    getBot,
    nextBot,
    logBot,
}

所以我们现在可以执行相同的实验并尝试从问题中打印出旧测试:

const bt = require('./VarTestFileA')
console.log(bt.getBot())

bt.nextBot()
bt.logBot()
console.log("O:", bt.getBot())

bt.nextBot()
bt.logBot()
console.log("O:", bt.getBot())

bt.nextBot()
bt.logBot()
console.log("O:", bt.getBot())

而output如下:

{ token: 2 }
I: { token: 3 }
O: { token: 3 }
I: { token: 2 }
O: { token: 2 }
I: { token: 3 }
O: { token: 3 }

结果很有趣,因为现在文件 A 中的bot似乎按预期进行切换。


在结论中,问题是通过引用或值传递属性。 初始代码中的bot按值传递,它不是一个复杂的项目,或者它没有声明为Object类型,但包含一个简单的 object 作为值。 所以没有办法通过引用传递bot 我有待纠正,但我认为不能通过引用传递像Boolean中的 Boolean 这样的原始值或作为值的简单对象的变量。 但是函数是复杂类型,这意味着它们是Object s,因此它们是通过引用传递的。

我希望你能按顺序找到这个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM