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

时间:2009-01-02 15:16:50

标签: javascript global-variables

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

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

10 个答案:

答案 0 :(得分:71)

我认为这里最好的选择可能是定义一个单个全局范围的变量,并将变量转储到那里:

var MyApp = {}; // Globally scoped object

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

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

没有人会因为做上述事情而对你大喊大叫。

答案 1 :(得分:51)

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

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

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

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

function B(r)
{
    use_rand_num(r);
}

答案 2 :(得分:14)

考虑使用名称空间:

(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 ed属性,例如ns.foo,同时仍保留对本地定义的访问权限。

答案 3 :(得分:7)

你所寻找的东西在技术上称为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));

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

答案 4 :(得分:4)

如果另一个函数需要使用变量,则将其作为参数传递给函数。

全球变量本身并不是恶劣的。只要它们使用得当,它们就没有问题。

答案 5 :(得分:2)

如果您有可能重用此代码,那么我可能会努力使用面向对象的视角。使用全局命名空间可能很危险 - 由于变量名称被重用,您将面临很难发现错误的风险。通常我首先使用面向对象的方法,而不仅仅是简单的回调,这样我就不必重写了。我认为,只要你在javascript中拥有一组相关的函数,它就是面向对象方法的候选者。

答案 6 :(得分:2)

另一种方法是我从Douglas Crockford论坛帖子(http://bytes.com/topic/javascript/answers/512361-array-objects)中选择的方法。这是......

道格拉斯·克罗克福德写道:

2006年7月15日

“如果你想通过id检索对象,那么你应该使用一个对象,而不是一个 阵列。由于函数也是对象,您可以将成员存储在 功能本身。“

function objFacility(id, name, adr, city, state, zip) {

    return objFacility[id] = {

        id: id,
        name: name,
        adr: adr,
        city: city,
        state: state,
        zip: zip

    }
}

objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);

“可以使用”

获取对象
objFacility.wlevine

现在可以从任何其他函数中访问对象属性。

答案 7 :(得分:2)

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

返回你想在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();

答案 8 :(得分:1)

我不知道您的问题的具体细节,但如果该函数需要该值,那么它可以是通过该调用传递的参数。

Globals被认为是错误的,因为全局状态和多个修饰符可能会导致难以遵循的代码和奇怪的错误。对许多摆弄东西的演员来说,可能会造成混乱。

答案 9 :(得分:1)

你可以使用自定义的jQuery事件完全控制javascript函数的执行(并在它们之间传递变量)....有人告诉我这不可能在这些论坛上,但我有一些工作正是这样做的(甚至使用ajax调用)。

这是答案(重要提示:这不是经过检查的答案,而是我的回答“Emile”):

How to get a variable returned across multiple functions - Javascript/jQuery