【问题标题】:Passing string into function doesn't set variable name将字符串传递给函数不会设置变量名
【发布时间】:2014-11-02 23:02:30
【问题描述】:

我有一个全局变量:

var chart;

创建图表的函数:

function setChart(variableName, chartContainer){

variableName = new CanvasJS.Chart(chartContainer, {**params**});

 variableName.render();

};

我调用 setChart

setChart(chart, "chartContainDiv");

如果我稍后再拨打chart.render();,它就不起作用了。

我怎样才能做到这一点? / 我误会了什么?

【问题讨论】:

  • 您误解了 JavaScript 的工作原理;你不能那样做。如果您想按名称引用变量,最接近的等效方法是创建一个对象并按名称引用其属性。
  • 那是相当的编辑。在任何情况下,问题都是一样的——您正在设置一个函数本地的变量。如果您需要多个实例,请使用一个对象,就像我已经说过的那样。如果您需要单个实例,则只需使用全局。
  • 您对传递by value and passing by reference 感到困惑。当您将chart 传递给setChart 时,您无法为其分配值,因为您没有传递它的引用,而是传递了它的值(在您的示例中为undefined)。
  • @DaveNewton 我知道,对不起,我正经历着这样的日子。
  • @AlexW 好的,所以如果我想执行上述操作,以便我可以使用 setChart 函数创建几个不同的图表,我该怎么做?

标签: javascript


【解决方案1】:

由于您将字符串传递给函数,因此您最终会尝试分配这个:

setVar("globalVar");
// In setVar...
"globalVar" = 5

这显然行不通。仅传入变量名本身将几乎按预期工作:

setVar(globalVar);
// In setVar...
globalVar = 5

但是

由于变量作用域,在setVar 函数中,您有一个与全局 同名的局部 变量。在这里进行任何赋值只会将 local 变量设置为 5,其中 global 变量将保持原来的值。

var myVar = 1;
function setVar(globalVar) { globalVar = 5; alert(globalVar); }
setVar(myVar); // alerts 5
alert(myVar); // alerts 1

有趣的是,如果您传入字符串,那么您可以通过window 对象上的数组访问来设置它:

setVar("globalVar");
// In setVar...
window[variableName] = 5; // window["globalVar"] = 5;

但试图通过传递变量本身来做到这一点是行不通的......

setVar(globalVar);
// In setVar...
window[globalVar] = 5; // window["5"] = 5 // or whatever globalVar contains

TLDR 版本是,这是您在 OP 中尝试执行此操作的唯一方法完全正确(尽管还有其他方法,例如 Ahmad 的回答,您在其中设置一个特定的变量而不传递它):

var myVar = 1;
function setVar(varName) { window[varName] = 5; }
setVar('myVar');

【讨论】:

  • 传入变量名将无法按预期工作,除非您不希望 globalVar 在函数外设置为 5。
  • 删除了我原来的评论,因为它不再是真的! :)
【解决方案2】:

首先你要清楚变量和全局变量的作用域。在您的示例中,没有将 globalVar 设置为 5 的行。您只需将名为 variableName 的函数 setVar 的局部变量设置为 5。

你应该做的是:

var globalVar;

function setVar(){
  globalVar = 5;
};

现在,如果您想拥有一个全局变量或一组全局变量,那么您应该将它们放在一个对象中,然后拥有一个函数,该函数采用该变量名和您要分配的可选值。

    var globalVariables = {"globalvar1" : "", "globalvar2" : "", .... };
    function setGlobalVar(variableName, Value) {
       globalVariables[variableName] = value;
    }

setGlobalVar ('globalvar1', 5); // this would do it

【讨论】:

  • window 是一个对象,变量在全局范围内,因此您可以通过window[variableName] 以数组表示法引用它们,而不必将它们放在另一个容器对象中
  • 最好的做法是尽量减少添加到 window 以保持全局命名空间干净 (stackoverflow.com/questions/3679634/…)
  • 绝对是,但他已经告诉我们这是一个全局变量(OP 的第 1 行),除非您将其范围限定在您未在答案中显示的其他内容中,否则您就是只是自己创建一个全局对象,称为window.globalVariables :-)
  • 我不清楚全局变量是在窗口还是在函数范围内:) 显然他现在编辑了这个问题
【解决方案3】:

将函数用作返回图表对象的factory,而不是将其传递给空变量。这使用了完全相同的概念,通过创建一个对象然后返回该对象,但为了简单起见,它不使用 CanvasJS 对象:

function setChart(chartContainer) {
    var variableName = new String(chartContainer);
    return variableName.toUpperCase();
};

var chart = setChart("chartContainDiv");
var chart2 = setChart("blahBlah");
console.log(chart.toString());    // "CHARTCONTAINDIV"
console.log(chart2.toString());   // "BLAHBLAH"

http://jsfiddle.net/n8Lg4wqy/3/

【讨论】:

  • 太棒了,谢谢,事实证明我几乎在那里,现在很有魅力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 2020-10-03
  • 2016-12-03
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
相关资源
最近更新 更多