我听说过全球变数不好,应该使用什么替代解决scheme?

我读过遍布全局variables不好的地方,应该使用替代方法。 在Javascript中,我应该select什么样的解决scheme。

我想到一个函数,当进给两个参数( function globalVariables(Variable,Value) )看起来是否存在本地数组中的variables,如果它确实将它的值设置为Value ,否则, VariableValue被追加。 如果该函数被调用没有参数( function globalVariables() )它返回数组。 也许如果只用一个参数( function globalVariables(Variable) )触发function globalVariables(Variable)它将返回数组中的Variable值。

你怎么看? 我想听听您使用全局variables的替代解决scheme和参数。

你将如何使用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". }; 

这是一个Singleton模式 BTW?

在这个特定的场景中,一个函数可能会在一个时间点上设置一个variables,而另外一个函数可能会在用户提交一个表单的时候需要获取这个variables。 因此,第一个函数不能将variables作为parameter passing给后面的函数,因为它从不会从第一个函数调用。

谢谢,我感谢你的帮助!

全局variables不鼓励在javascript中的主要原因是因为,在所有的JavaScript代码共享一个单一的全局命名空间,也有JavaScript隐含的全局variables,即。 在本地作用域中未明确声明的variables会自动添加到全局名称空间中。 依赖全局variables可能会导致同一页面上的各种脚本之间发生冲突(请阅读douglas crockford的文章 )。

减less全局variables的一种方法是使用YUI模块模式 。 基本的想法是将所有代码包装在一个函数中,该函数返回一个包含需要在模块外访问的函数的对象,并将返回值分配给一个全局variables。

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

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

语义我的孩子。 语义。

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

myApp中应该只有很less的属性。 你会想要把你的应用程序属性保存在诸如configuration或设置的容器中。

 myApp = { config:{ prop:1 }, settings:{ prop:2 }, widgets:{ List: function(props){}, Item: function(props){} } } 

那么你可能会有更多的属性在较低的模块,组件,单例和类构造函数(小部件)。

此设置为您提供了可以从任何其他位置访问任何属性的额外好处,因为您可以通过myApp全局访问它。 但是,您应该尽可能使用“this”,因为查找速度更快。 直接设置属性,不要打扰伪造的getter / setter的东西。 如果你确实需要一个getter / setter,那就为了这个特定的用途编码。

你的例子不起作用的原因是它太通用了,你似乎正在寻找一个在全球空间工作的借口。

而且不要使用私有variables。 他们也不好: http : //clubajax.org/javascript-private-variables-are-evil/

全球性国家在几个领域造成问题。 一个是代码重用。 当你访问某个全局​​状态时,意味着组件必须意识到它的环境(它本身以外的东西)。 您应尽可能避免这种情况,因为这会使组件变得不可预知。

说我有一个对象访问您的globalVariables函数,我想在另一个页面中使用它。 我怎么知道定义globalVariables对象,甚至如何定义呢? 但是,如果您可以将信息传递给构造函数或作为函数的参数,那么我可以轻松地确定该对象需要什么。

另外,当您访问或修改全局范围时,则可能会影响其他对象。 这就是为什么类似jQuery的图书馆在全球范围内只使用一个名字(尽可能less)。 它减less了与其他图书馆冲突的可能性。 换句话说,全球范围超出了你的控制范围,所以这是危险的。

你真的不想这样做。
至于为什么,请参阅这里的顶部post: 什么是您在生产企业环境中见过的最多的EVIL代码?

作为一个方面说明,可以始终执行“全局”代码,而不用乱扔乱七八糟的地方:

 (function () { var notaglobal = 1; alert(notaglobal); })(); //notaglobal is not defined in this scope 

无论select何种语言,使用全局variables通常都是不好的做法。 在严格模式下 ,他们甚至不能(很容易)使用,我强烈build议。

考虑一下我发现的这段代码:

 if (typeof session != 'undefined' && !data.cart.request_status) data.input_definitions.passengers = inflate_passenger(session, data.input_definitions.passengers); 

我需要转过头来问一个felow程序员这个sessionvariables是从哪里来的,因为没有代码search显示在哪里设置。

我发现公司的另一个软件包设置了全局variables。 编码就像一个笑话:如果你需要解释它可能不是那么好。

使用ES6的解决方法:

如果在Node上,使用importrequire将所需的东西放到词法范围内,不要让人们在你不知道的情况下触及你的全局环境。

 import {Sesssion} from 'api-core'; const Session = require('api-core').session; 

如果您在前端为浏览器提供代码,那么除非使用Babel来传输ES6代码,否则不能使用import

使用Gulp.js的示例传输:

 // $ npm install --save-dev gulp-babel babel-preset-es2015 // gulpfile.js const gulp = require('gulp'); const babel = require('gulp-babel'); gulp.task('transpile', () => { return gulp.src('src/app.js') .pipe(babel({presets: ['es2015']})) .pipe(gulp.dest('dist')); }); // $ gulp transpile 

传统解决方法:

当使用ES6function不是一个选项唯一的解决方法,使用一堆全局variables,只使用一个,并有希望:

 // scripts/app.js var MyApp = { globals: { foo: "bar", fizz: "buzz" } }; 

你的解决scheme的问题是,它只是让你的代码更难以理解,同时仍然保持全局variables的所有缺点。 您链接的页面覆盖了问题。 您提出的解决scheme真正解决的唯一问题是名称空间污染,但代价是无法看到声明的全局variables是如函数调用那样容易声明的)。

解决scheme是编写没有全局variables的代码。 如果一个函数需要一个值作为parameter passing它。

其他答案大部分以匿名函数解释为本文所提,

匿名函数很难debugging,维护,testing或重用。

这里是正常function的例子。 阅读和理解起来更容易。

 /* global variable example */ var a= 3, b= 6; function fwithglobal(){ console.log(a, b); // 3 6 expected } fwithglobal(); // first call function swithglobal(){ var a=9; console.log(a, b); // not 3 6 but 9 6 } swithglobal(); // second call /* global variable alternative(function parameter) */ function altern(){ var a= 3, b= 6; // var keyword needed f_func(a,b); s_func(a,b); } function f_func(n, m){ console.log(n, m); // 3 6 expected } function s_func(n, m){ var a=9; console.log(n, m); // 3 6 expected } altern(); // only once 

全局variables不好…如果不加pipe理!

全球variables的潜在风险与经常使用的物体随时可以使用的快感和生产力收益一样高。

我不相信应该寻求一个单一的select。 相反,我主张负责pipe理这些全局variables的一个对象,随着代码库/组件的成熟,将它们重构出来

在我认为关键的当前答案中没有提到的一件事是了解DI和IoC容器。 这些解决了人们试图用全局variables解决的许多问题,但是涉及到全局variables不能像物体生命周期那样的相关问题。