不使用全局变量访问其他函数中的变量

时间:2022-08-24 16:27:59

I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.

我从很多地方听说全局变量本质上是令人讨厌的和邪恶的,但是当执行一些非面向对象的Javascript时,我不知道如何避免它们。假设我有一个函数用一个复杂的算法用随机数来生成一个数字,但是我需要继续在其他函数中使用这个特定的数字也就是回调函数,所以不能是同一个函数的一部分。

If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?

如果最初生成的数字是一个局部变量,那么它将无法从那里访问。如果函数是对象方法,我可以把数字设为属性,但它们不是,改变整个程序结构来做这个有点复杂。一个全局变量真的很糟糕吗?

10 个解决方案

#1


43  

To make a variable calculated in function A visible in function B, you have three choices:

为了使函数B中可以看到的变量,你有三个选择:

  • make it a global,
  • 使它成为一个全球性的,
  • make it an object property, or
  • 使它成为对象属性,或者
  • pass it as a parameter when calling B from A.
  • 当从a调用B时,将其作为参数传递。

If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:

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

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

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

#2


63  

I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:

我认为你最好的选择可能是定义一个全局范围的变量,然后把你的变量放在那里:

var MyApp = {}; // Globally scoped object

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

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

No one should yell at you for doing something like the above.

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

#3


13  

Consider using namespaces:

考虑使用名称空间:

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

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

Both local_function and global_function have access to all local and global variables.

local_function和global_function都可以访问所有本地和全局变量。

Edit: Another common pattern:

编辑:另一个常见的模式:

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

The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.

返回的属性现在可以通过名称空间对象来访问,例如ns。但仍然保留对本地定义的访问权限。

#4


7  

What you're looking for is technically known as 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));

The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.

上面的函数并不是一个受到限制的函数,但是它实现了在不向全局命名空间添加变量或需要其他对象存储库的情况下维护现有值的结果。

#5


3  

If another function needs to use a variable you pass it to the function as an argument.

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

Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.

同样,全局变量也不是天生就讨厌和邪恶的。只要他们使用得当,他们就不会有问题。

#6


2  

Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...

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

Douglas Crockford wrote:

道格拉斯Crockford写道:

Jul 15 '06

7月15日06年

"If you want to retrieve objects by id, then you should use an object, not an array. Since functions are also objects, you could store the members in the function itself."

“如果您想通过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);

"The object can be obtained with"

"对象可以通过"

objFacility.wlevine

The objects properties are now accessable from within any other function.

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

#7


2  

I found this to be extremely helpful in relation to the original question:

我发现这对最初的问题非常有帮助:

Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.

返回您希望在functionOne中使用的值,然后在functionTwo中调用functionOne,然后将结果放在一个新的var中,并在functionTwo中引用这个新的var。这将使您能够在functionOne和functionTwo中使用所声明的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  

If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.

如果您有机会重用这段代码,那么我可能会尝试使用面向对象的视角。使用全局名称空间可能是危险的——由于变量名被重用,您可能很难找到bug。通常,我从使用面向对象的方法开始,而不是使用简单的回调,这样我就不必重新编写了。在javascript中有一组相关函数的时候,我认为它是面向对象方法的候选。

#9


1  

I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.

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

Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.

通配符被认为是不好的,因为通配符状态和多个修饰符会导致难以跟踪代码和奇怪的错误。对许多演员来说,摆弄东西会造成混乱。

#10


1  

You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).

你可以完全控制的执行javascript函数(和)之间传递变量.... jQuery使用自定义事件有人告诉我,在所有这些论坛上都不可能实现这一点,但我得到了一些能够实现这一点的东西(甚至使用ajax调用)。

Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):

这里有一个答案(重要的是:它不是检查过的答案,而是我“埃米尔”的答案):

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

如何获得跨多个函数返回的变量—Javascript/jQuery

#1


43  

To make a variable calculated in function A visible in function B, you have three choices:

为了使函数B中可以看到的变量,你有三个选择:

  • make it a global,
  • 使它成为一个全球性的,
  • make it an object property, or
  • 使它成为对象属性,或者
  • pass it as a parameter when calling B from A.
  • 当从a调用B时,将其作为参数传递。

If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:

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

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

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

#2


63  

I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:

我认为你最好的选择可能是定义一个全局范围的变量,然后把你的变量放在那里:

var MyApp = {}; // Globally scoped object

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

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

No one should yell at you for doing something like the above.

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

#3


13  

Consider using namespaces:

考虑使用名称空间:

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

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

Both local_function and global_function have access to all local and global variables.

local_function和global_function都可以访问所有本地和全局变量。

Edit: Another common pattern:

编辑:另一个常见的模式:

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

The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.

返回的属性现在可以通过名称空间对象来访问,例如ns。但仍然保留对本地定义的访问权限。

#4


7  

What you're looking for is technically known as 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));

The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.

上面的函数并不是一个受到限制的函数,但是它实现了在不向全局命名空间添加变量或需要其他对象存储库的情况下维护现有值的结果。

#5


3  

If another function needs to use a variable you pass it to the function as an argument.

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

Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.

同样,全局变量也不是天生就讨厌和邪恶的。只要他们使用得当,他们就不会有问题。

#6


2  

Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...

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

Douglas Crockford wrote:

道格拉斯Crockford写道:

Jul 15 '06

7月15日06年

"If you want to retrieve objects by id, then you should use an object, not an array. Since functions are also objects, you could store the members in the function itself."

“如果您想通过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);

"The object can be obtained with"

"对象可以通过"

objFacility.wlevine

The objects properties are now accessable from within any other function.

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

#7


2  

I found this to be extremely helpful in relation to the original question:

我发现这对最初的问题非常有帮助:

Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.

返回您希望在functionOne中使用的值,然后在functionTwo中调用functionOne,然后将结果放在一个新的var中,并在functionTwo中引用这个新的var。这将使您能够在functionOne和functionTwo中使用所声明的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  

If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.

如果您有机会重用这段代码,那么我可能会尝试使用面向对象的视角。使用全局名称空间可能是危险的——由于变量名被重用,您可能很难找到bug。通常,我从使用面向对象的方法开始,而不是使用简单的回调,这样我就不必重新编写了。在javascript中有一组相关函数的时候,我认为它是面向对象方法的候选。

#9


1  

I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.

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

Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.

通配符被认为是不好的,因为通配符状态和多个修饰符会导致难以跟踪代码和奇怪的错误。对许多演员来说,摆弄东西会造成混乱。

#10


1  

You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).

你可以完全控制的执行javascript函数(和)之间传递变量.... jQuery使用自定义事件有人告诉我,在所有这些论坛上都不可能实现这一点,但我得到了一些能够实现这一点的东西(甚至使用ajax调用)。

Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):

这里有一个答案(重要的是:它不是检查过的答案,而是我“埃米尔”的答案):

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

如何获得跨多个函数返回的变量—Javascript/jQuery