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

Javascript 在不使用全局变量的情况下访问其他函数中的变量,javascript,global-variables,Javascript,Global Variables,我从很多地方听说,全局变量本质上是令人讨厌和邪恶的,但在执行一些非面向对象的Javascript时,我看不出如何避免它们。假设我有一个函数,它使用一个复杂的算法生成一个数字,使用随机数之类的东西,但我需要在其他函数中继续使用这个特定的数字,它是回调函数或其他什么函数,因此不能是同一个函数的一部分 如果最初生成的数字是一个局部变量,则无法从那里访问它。如果函数是对象方法,我可以将数字作为一个属性,但它们不是,而且改变整个程序结构来实现这一点似乎有点过于复杂。全局变量真的那么糟糕吗?如果另一个函数需

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


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

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


此外,全球变量并非天生令人讨厌和邪恶。只要正确使用,它们就没有问题。

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

  • 让它成为一个全球性的
  • 使其成为对象属性,或
  • 从a调用B时将其作为参数传递
如果你的程序相当小,那么全局的就不那么糟糕了。否则我会考虑使用第三种方法:

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

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

如果有机会重用此代码,那么我可能会努力使用面向对象的透视图。使用全局名称空间可能是危险的,因为变量名会被重用,所以很难找到bug。通常,我首先使用面向对象的方法进行简单回调以外的任何操作,这样我就不必重新编写。我认为,在javascript中有一组相关函数的任何时候,它都是面向对象方法的候选者。

从技术上讲,您所寻找的就是所谓的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));

上述函数并不完全是一个通用函数,但它实现了维护现有值的结果,而无需向全局名称空间添加变量或为其添加其他对象存储库。

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


全局被认为是不好的,因为全局状态和多个修饰符会创建难以理解的代码和奇怪的错误。对许多演员来说,摆弄一些东西会造成混乱

我认为您最好在这里定义一个全局范围的变量,并将变量转储到那里:

var MyApp = {}; // Globally scoped object

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

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

任何人都不应该因为你做了上述事情而对你大喊大叫。

考虑使用名称空间:

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

    function local_function() {}
    global_function = function() {};
})();
local_函数
global_函数
都可以访问所有局部和全局变量

编辑:另一种常见模式:

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
,同时仍然保留对本地定义的访问。

您可以完全控制javascript函数的执行(并在它们之间传递变量)使用自定义jQuery事件……我被告知这在所有这些论坛上都是不可能的,但我得到了一些可以做到这一点的东西(甚至使用ajax调用)

以下是答案(重要提示:这不是核对答案,而是我“Emile”的答案):


另一种方法是我从道格拉斯·克罗克福德论坛的帖子()中找到的。这是

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

2006年7月15日

如果要按id检索对象,则应使用对象,而不是 由于函数也是对象,所以可以将成员存储在 功能本身。”

“可以通过以下方式获取对象”


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

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

返回希望在functionOne中使用的值,然后在functionTwo中调用functionOne,然后将结果放入一个新的变量,并在functionTwo中引用这个新的变量。这应该使您能够在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();

全局变量在Javascript中是极其有害的-1.-1. 这不仅不是一个讨好的例子,而且这个问题的答案太复杂了。@triptych:我不同意。对于这类问题,这是一个非常有效和有趣的解决方案,并且完全是currying()+1混淆。。。那就开明了!我清楚地看到,
myCallback
是对
getMyCallback
返回的函数的引用,该函数已设置了
randomValue
。使用
getRand
也很有指导意义,因为我看到多次调用
myCallBack(1)
将返回相同的值,因此
myCallBack
等于从
getMyCallBack(getRand())
返回的值,而不仅仅是对函数本身的引用。大声说出来很有帮助:)不要污染全局名称空间!最糟糕的情况应该是使用一个自定义全局对象创建一个对象属性,这是我提出的第四个选项,而这三个选项对我都不起作用。(参见Emile的答案)ps.pm在上面的链接上,查找“Emile”未经检查的答案。我知道这已经很老了,但我只是想知道,在大型程序中广泛使用第三种方法不会导致意大利面代码吗?所以这是咖喱?我一直在想这个问题,这真的很简单example@annakata因为有很多自以为是的用户,所以您的示例的问题是javascript处理嵌套对象的时间更长。(这将花费很长时间:
MyApp.something.color.somethingElse
Progo,这不是一个真正的问题。函数
var()
应该更改为
bar()
,这个小语法错误
objFacility.wlevine
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();