我听说全球变量很糟糕,我应该使用哪种替代解决方案?

Jon*_*tes 71 javascript global-variables

我已经读过全局变量都不好的地方,应该使用替代方案.在Javascript中,我应该选择什么解决方案.

我正在考虑一个函数,当有两个arguments(function globalVariables(Variable,Value))时,看看Variable是否存在于一个本地数组中,并且它是否将它的值设置为Value,else,Variable并被Value追加.如果在没有arguments(function globalVariables())的情况下调用该函数,则返回该数组.也许如果仅使用一个参数(function globalVariables(Variable))触发该函数,它将返回Variable数组中的值.

你怎么看?我想听听你使用全局变量的替代解决方案和论据.

你会怎么用 globalVariables();

function append(){
    globalVariables("variable1","value1"); //globalVariables() would append variable1 to it's local array.
};

function retrieve(){
    var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};

function retrieveAll(){
    var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()'s entire, local [persistently stored between calls] array.
};

function set(){
    globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};
Run Code Online (Sandbox Code Playgroud)

这是Singleton Pattern BTW吗?

在这个特定场景中,函数可以在一个时间点设置变量,并且很晚以后另一个函数,可能在用户提交表单时,将需要获得该变量.因此,第一个函数无法将变量作为参数传递给后一个函数,因为它永远不会从第一个函数调用.

谢谢,谢谢你的帮助!

z33*_*33m 132

在javascript中不鼓励全局变量的主要原因是因为,在javascript中所有代码共享一个全局命名空间,javascript也隐含了全局变量,即.未在本地范围内显式声明的变量会自动添加到全局命名空间.过分依赖全局变量可能会导致同一页面上各种脚本之间发生冲突(阅读Douglas Crockford的文章).

减少全局变量的一种方法是使用YUI模块模式.基本思想是将所有代码包装在一个函数中,该函数返回一个对象,该对象包含需要在模块外部访问的函数,并将返回值赋给单个全局变量.

var FOO = (function() {
    var my_var = 10; //shared variable available only inside your module

    function bar() { // this function not available outside your module
        alert(my_var); // this function can access my_var
    }

    return {
        a_func: function() {
            alert(my_var); // this function can access my_var
        },
        b_func: function() {
            alert(my_var); // this function can also access my_var
        }
    };

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

现在要在你的模块中使用其他功能,使用FOO.a_func().这种解决全局命名空间冲突的方法只需要更改名称FOO.

  • 嘿嘿 - 那最后两个括号是一个难题!没有它们你需要引用`FOO().a_func()`.啊它现在开始有意义啊! (6认同)
  • 所以命名冲突是唯一的原因?? 还是有内存使用的缺点也? (3认同)
  • 太酷了,它将完全重写我的代码,但是我已经完成了,太好了,已经接受了答案。 (2认同)

mwi*_*cox 40

语义学我的孩子.语义.

从一个全局开始:myApp = {}; 一切都应该在那里.唯一的例外是你的AJAX库(有一些极端的例外,比如使用JSONP回调).

myApp中的属性应该很少.您需要将容器中的应用程序属性保存在配置或设置中.

myApp = {
    config:{
        prop:1
    },
    settings:{
        prop:2
    },
    widgets:{
        List: function(props){},
        Item: function(props){}
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在较低的模块,组件,单例和类构造函数(小部件)中拥有更多属性.

此设置为您提供了从任何其他位置访问任何属性的额外好处,因为您可以使用myApp global获取它.但是,您应尽可能使用"this",因为查找速度更快.只需直接设置属性,不要打扰伪getter/setter的东西.如果您确实需要getter/setter,请为特定用途编写代码.

你的例子不起作用的原因是它过于通用,你似乎在找借口在全球空间工作.

私有变量并不聪明.它们也很糟糕:http: //clubajax.org/javascript-private-variables-are-evil/

  • 伟大的评论mwilcox.我用这篇文章来说服其他人在这里工作. (2认同)

Lee*_*Lee 9

全球国家在若干领域引起问题.一个是代码重用.当您访问某个全局​​状态时,意味着组件必须知道它的环境(本身之外的东西).你应该尽可能地避免这种情况,因为它会使组件变得不可预测.

假设我有一个访问globalVariables函数的对象,我想在另一个页面中使用它.我如何知道定义globalVariables对象甚至如何定义它?但是,如果您可以将信息传递给构造函数或作为函数的参数,那么我可以轻松确定对象所需的内容.

此外,当您访问或修改全局范围时,您可能会影响其他对象.这就是为什么像jquery这样的库在全局范围内只使用一个名称(尽可能少).它减少了与其他图书馆发生冲突的可能性.换句话说,全局范围是您无法控制的,因此它很危险.