【问题标题】:Passing a reference of a global variable to a function将全局变量的引用传递给函数
【发布时间】:2015-06-15 19:31:26
【问题描述】:

是否可以将指向全局变量的链接发送到 JavaScript 中的函数? This answer 说不,但我不敢相信,没有解决方法。

我的意思是类似于以下内容。它不起作用,但它应该解释我的意思:

var data_1;
var data_2;

fillValue(data_1,"First");
fillValue(data_2,"Second");

function fillValue(link2GlobalVar, value){
    link2GlobalVar = value;
}   

console.log(data_1);
console.log(data_2);

如果能在控制台输出就好了

First
Second

您知道将全局变量发送到函数并在其中更改它们的技巧吗?

Fiddle

【问题讨论】:

标签: javascript global-variables parameter-passing


【解决方案1】:

JavaScript 不像其他语言那样有引用。当您执行fillValue(data_1,"First"); 时,您将通过值传递data_1。因此,您无法更新 data_1,因为在函数中您所拥有的只是数据的副本

如果这些变量是全局,那么您可以按照链接答案的建议进行操作并传递变量名称:

fillValue("data_1", "First");
fillValue("data_2", "Second");

function fillValue(link2GlobalVar, value){
    window[link2GlobalVar] = value;
}

更新: 在 JavaScript 中,如果您将 object 作为参数传递,那么 it 实际上是通过引用传递的。你可以试试这样:

var datas = {};

fillValue(datas, "data_1", ,"First");
fillValue(datas, "data_2", "Second");

function fillValue(obj, key, value){
    obj[key] = value;
}

【讨论】:

  • @blex - 答案相同,只是解释得更好。
  • @adeneo 抱歉,我被冲昏了头脑,以为 OP 已经在传递一个字符串作为变量名,就像在 the answer he linked 中一样。 +1
  • @blex - 实际上,Crayons 的答案似乎是错误的,因为它传递了一个字符串,并且该答案不起作用。
  • 如果我们不想假设有一个浏览器,因此,一个window 对象,这会更好吗? jsfiddle.net/j90kurvy
  • 我愿意承认(并删除我的答案)它被作为变量引用而不是字符串传递(尽管我真的责怪 OP,而不是我的答案)但重新:“也许不是浏览器”我想你们都看得太远了哈哈
【解决方案2】:

原始值不通过引用传递。 对象是。

如果您将全局变量包装在一个对象中,您将能够通过函数修改其属性:

var data_1 = {};
var data_2 = {};


fillValue(data_1,"First");
fillValue(data_2,"Second");

function fillValue(link2GlobalVar, value){
    link2GlobalVar.value = value;
}   

document.write(data_1.value + "<br/>" +data_2.value);

除此之外,this 应该比window 更便携。 (适用于浏览器和nodejs)。如果您处于严格模式,则不能从内部函数(不使用 new 调用)中使用它,但您可以在全局范围内使用它来获取对全局范围的引用。

"use strict";
var data_1;
var data_2;
var global = this;  //get a reference to the global object
    
fillValue("data_1","First");
fillValue("data_2","Second");

function fillValue(globalVariableName, value){
    //`this` instead of `global` would work here only if you're not in strict mode
    global[globalVariableName] = value;
}   

document.write(data_1 + "<br/>" +data_2);

【讨论】:

  • 我比我自己的答案更喜欢这个。它可能更接近 OP 想要的。
  • 我实际上不会使用this。它在“严格模式”下不起作用。来自MDN Docs:“在浏览器中,不再可能在严格模式函数中通过this 引用window 对象。”
  • 感谢 node.js 的提示!
  • 感谢@RocketHazmat 的评论。我已经修改了第二个解决方案以使其解决这个问题。适用于我的 chromium、firefox 和 node。
【解决方案3】:

这个问题似乎有点疯狂,但你可以将全局名称作为字符串传递,然后使用 eval 进行设置:

function blah(nameAsString, val){ eval("window." + name + " = " + val);}

更疯狂! :)

【讨论】:

  • 这是一个潜在的安全漏洞(而且是一个巨大的漏洞),除非您对事物进行清理。
  • 请不要真的这样做。你为什么要在eval() 里面做"window." + name 而不是window[name] 而没有eval()
  • 如果要使用字符串构造变量,使用 eval 的选项实际上是一个不错的选择。我试图让这个例子运行(jsfiddle.net/gulli/7ft65ma5)但我没有成功。有什么办法可以解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 2014-05-14
相关资源
最近更新 更多