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

IT技术 javascript global-variables
2021-01-20 08:43:13

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

如果最初生成的数字是局部变量,则无法从那里访问它。如果函数是对象方法,我可以使数字成为一个属性,但它们不是,更改整个程序结构来执行此操作似乎有些过于复杂。全局变量真的那么糟糕吗?

6个回答

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

var MyApp = {}; // Globally scoped object

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

function bar(){
    alert(MyApp.color); // Alerts 'green'
} 

没有人应该因为你做了上面那样的事情而对你大喊大叫。

该函数var()应该更改为bar(),这个微小的语法错误可能会让后来的人头疼。
2021-03-13 08:43:13
Progo,这不是真正的问题。
2021-03-21 08:43:13
三联画,感谢您为我的工作保障做出贡献:p
2021-04-03 08:43:13
谢谢,正是我需要的!但我不明白,MyApp.color如果foo()从不调用应该如何创建和填充
2021-04-06 08:43:13
您的示例的问题在于,javascript 处理嵌套对象需要更长的时间。(这将需要很长时间:MyApp.something.color.somethingElse
2021-04-10 08:43:13

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

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

如果您的程序相当小,那么全局变量还不错。否则我会考虑使用第三种方法:

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

function B(r)
{
    use_rand_num(r);
}
我知道这已经很老了,但我只是想知道,在大型程序中广泛使用第三种方法会不会导致意大利面条式代码?
2021-03-22 08:43:13
我想出了第 4 个选项,但所有 3 个选项都不适合我。 stackoverflow.com/questions/3531080/... (见埃米尔的回答)
2021-03-25 08:43:13
不要污染全局命名空间!您最坏的回退应该只是使用单个自定义全局对象创建对象属性
2021-03-30 08:43:13
附:pm 在上面的链接上,寻找“Emile”的未经检查的答案
2021-04-07 08:43:13
所以这是柯里化?一段时间以来我一直试图解决这个问题,这是一个非常简单的例子
2021-04-08 08:43:13

考虑使用命名空间:

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

    function local_function() {}
    global_function = function() {};
})();

双方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
    };
})();

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

超级棒的答案!终于有了像其他语言一样的类结构:)
2021-03-16 08:43:13
这很好,这应该是公认的答案。第二种模式显然被称为“具有对象模式的静态命名空间”,如在:javascriptweblog.wordpress.com/2010/12/07/...
2021-04-07 08:43:13

您要查找的内容在技术上称为柯里化。

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));

以上不完全是一个柯里化函数,但它实现了维护现有值的结果,而无需向全局命名空间添加变量或需要其他一些对象存储库。

@triptych:我不同意。这是解决此类问题的一个完全有效且有趣的解决方案,并且完全是柯里化的(dustindiaz.com/javascript-curry
2021-03-18 08:43:13
+1令人困惑......然后有启发性!一旦我清楚地看到这myCallbackgetMyCallbackrandomValue已设置返回的函数的引用的使用也getRand很有启发性,因为我看到myCallBack(1)多次调用将返回相同的值,因此myCallback等于返回的值getMyCallBack(getRand()),而不仅仅是对函数本身的引用。它有助于大声说出来:)
2021-03-19 08:43:13
-1. 这不仅不是柯里化的例子,而且这个问题的答案太复杂了。
2021-04-02 08:43:13

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

返回您希望在 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();