在不使用全局变量的情况下从其他函数访问变量

65 javascript global-variables

我从各种各样的地方听说全局变量本质上是讨厌和邪恶的,但是当做一些非面向对象的Javascript时,我看不出如何避免它们.假设我有一个使用随机数和东西使用复杂算法生成数字的函数,但我需要在其他函数中继续使用该特定数字,这是一个回调或其他函数,因此不能成为同一函数的一部分.

如果最初生成的数字是局部变量,那么就无法访问它.如果函数是对象方法,我可以将数字作为属性,但它们不是,并且看起来有点过于复杂,以改变整个程序结构来执行此操作.全局变量真的如此糟糕吗?

Tri*_*ych 73

我想在这里你最好的选择可能是定义一个单一的全球范围的变量,并且有倾倒的变量:

var MyApp = {}; // Globally scoped object

function foo(){
    MyApp.color = 'green';
}

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 
Run Code Online (Sandbox Code Playgroud)

做上述事情的人不应该对你大喊大叫.

  • Progo,这不是一个真正的问题. (19认同)
  • 函数`var()`应该更改为`bar()`,这个微小的语法错误可能是一个令人头疼的人. (6认同)
  • 谢谢,正是我需要的!但我不明白,如果从未调用“foo()”,应该如何创建和填充“MyApp.color”? (2认同)
  • Triptych,感谢您为我的工作保障做出的贡献:p (2认同)

Pau*_*son 52

要使函数A中计算的变量在函数B中可见,您有三个选择:

  • 使它成为一个全球的,
  • 使它成为一个对象属性,或
  • 从A调用B时将其作为参数传递

如果你的程序相当小,那么全局变量就不那么糟了.否则我会考虑使用第三种方法:

function A()
{
    var rand_num = calculate_random_number();
    B(rand_num);
}

function B(r)
{
    use_rand_num(r);
}
Run Code Online (Sandbox Code Playgroud)

  • 不要污染全局命名空间!您最糟糕的情况下,后备应该只是使用单个自定义全局对象创建对象属性 (4认同)

Chr*_*oph 15

考虑使用命名空间:

(function() {
    var local_var = 'foo';
    global_var = 'bar'; // this.global_var and window.global_var also work

    function local_function() {}
    global_function = function() {};
})();
Run Code Online (Sandbox Code Playgroud)

双方local_functionglobal_function可以访问所有本地和全局变量.

编辑:另一种常见模式:

var ns = (function() {
    // local stuff
    function foo() {}
    function bar() {}
    function baz() {} // this one stays invisible

    // stuff visible in namespace object
    return {
        foo : foo,
        bar : bar
    };
})();
Run Code Online (Sandbox Code Playgroud)

return编辑性能现在可以通过命名空间对象,如访问ns.foo,同时仍保留访问本地定义.


Ant*_*nes 8

您正在寻找的是技术上称为currying.

function getMyCallback(randomValue)
{
    return function(otherParam)
    {
        return randomValue * otherParam //or whatever it is you are doing.
    }

}

var myCallback = getMyCallBack(getRand())

alert(myCallBack(1));
alert(myCallBack(2));
Run Code Online (Sandbox Code Playgroud)

上面的内容并不完全是一个curried函数,但它实现了维护现有值的结果,而无需向全局命名空间添加变量或者需要一些其他对象存储库.

  • @triptych:我不同意.对于这类问题,这是一个非常有效和有趣的解决方案,而且正是这样的问题(http://www.dustindiaz.com/javascript-curry/) (5认同)

小智 5

我发现这对原始问题非常有帮助:

返回您希望在 functionOne 中使用的值,然后在 functionTwo 中调用 functionOne,然后将结果放入一个新的 var 并在 functionTwo 中引用这个新的 var。这应该使您能够在 functionTwo 中使用在 functionOne 中声明的 var。

function functionOne() {
  var variableThree = 3;
  return variableThree;
}

function functionTwo() {
  var variableOne = 1;
  var var3 = functionOne();

  var result = var3 - variableOne;

  console.log(variableOne);
  console.log(var3);
  console.log('functional result: ' + result);
}

functionTwo();
Run Code Online (Sandbox Code Playgroud)