在 .js 文件中声明全局变量是否不好
Is it bad practice declaring global variables in a.js file?
>我有一个.js文件,我正在初始化两个使用的参数在一个单独的函数中:
var submyvar1;
var submyvar2;
function init(myvar1 , myvar2){
submyvar1= myvar1;
submyvar2= myvar2;
}
function (){
//subvar1 & subvar 2 used here
}
像这样声明全局变量是一种不好的做法吗?
如果是这样,有什么替代方案,将整个.js文件包装在一个对象中?
至少这不是一个好的做法,你可以使用立即调用的函数表达式:
(function() {
var x;
var y;
window.init = function(xValue, yValue) {
x = xValue;
y = yValue;
}
window.doWhateverYouWant = function() {
console.log(x + y);
}
}());
您可以使用此模式,除非您需要在此.js文件之外访问全局变量,当需要.js文件或<script>
元素之间的交叉访问时,全局变量是一个简单的解决方案(尽管您可以使用 AMD 或 sth 代替)。
我决定使用揭示模块模式,如中所述:关于使用"揭示模块模式"的可能实现的好文章:http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
它与公认的答案非常相似。
这是从上面的企业jquery粘贴的模式解释:
We looked at the Self-Executing Anonymous Function earlier as a pattern you could use to keep all your code private. As it turns out, you can actually modify the pattern somewhat so that you can achieve the same benefits of the Revealing Module Pattern. Not only can we achieve public and private properties and methods, but we can also provide an easy way to extend the namespace while keeping the content protected from the global namespace. In addition, the following pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined.
Take a look at the following example, and we will walk through the code explaining the key changes to the pattern.
//Self-Executing Anonymous Func: Part 2 (Public & Private)
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "'t'n Butter 'n't" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
//Public Properties
console.log( skillet.ingredient ); //Bacon Strips
//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips
//Adding a Public Property
skillet.quantity = "12";
console.log( skillet.quantity ); //12
//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
try {
//12 Bacon Strips & 1 Cup of Grease
skillet.toString(); //Throws Exception
} catch( e ) {
console.log( e.message ); //isHot is not defined
}
You can execute and modify the above code from jsFiddle.
First, since we have a Self-Executing Anonymous Function, we can actually provide some parameters to pass to it when it executes. In this case we are passing 2 arguments to the anonymous function.
The first argument looks quite strange. What is window.skillet = window.skillet || {} doing? The code checks to see if skillet exists in the global namespace (window). If it does not exist, then window.skillet is assigned an empty object literal. Using this approach we can build a library across JavaScript files. If another script uses the same technique, then it will pass in the existing instance and append logic to it. Inside the Anonymous Function, if we want something to be public, then we append it to the skillet object. Any other properties or methods will be considered private.
The second argument passed in jQuery. The benefit of this is that the named parameter is referenced as $, which allows us to refer to jQuery as $ within the Anonymous Function without having to worry that it will conflict with the $ declared in other JavaScript libraries. This is a common practice that you will most likely run across when looking at well written jQuery code.
You might notice a 3rd parameter to the Anonymous Function called undefined. Why did we add that parameter and why didn’t we pass an argument to it? In JavaScript, you can unfortunately redefine what undefined means. Imagine that some code somewhere deep in one of your 3rd party libraries redefines undefined to something strange like true. If anywhere in your code you test against undefined, then you code will most likely not behave like you intended. In JavaScript, if you have a parameter that doesn’t have a matching argument, then it’s value is set as undefined. By using this trick, it can save us from the bad code someone wrote to redefine undefined.
Pros
Gives you the ability to have public and private properties and methods
The code inside doesn’t use the Object Literal notation
Keeps undefined’s value as undefined in case someone overrode the value
Allows you to use $ inside your code without worrying about clashing with other libraries
Allows your library to grow across files using the “window.namespace = window.namespace || {}” technique
A common pattern that you will see in many libraries, widgets, and plugins
Cons
Slightly more complicated pattern, but not overly difficult to understand
If you are interested in digging deeper into some of the patterns I mentioned above then I encourage you to check out Klaus Komenda’s post entitled JavaScript Programming Patterns. The article provides an insightful view of how JavaScript patterns have changed over the years.
应尽可能避免使用它,以防止全局命名空间混乱。不过,您可能想要公开一些代码,所以在这种情况下没关系。例如,jQuery显然必须使jQuery
和$
变量成为全局变量(它通过使它们成为window
的属性来实现这一点。
为了避免这种情况,您可以将代码包含在一个后面带有括号的函数中:
var mySingleGlobalVar = (function () {
var submyvar1;
var submyvar2;
function init(myvar1 , myvar2){
submyvar1= myvar1;
submyvar2= myvar2;
}
function (){
//subvar1 & subvar 2 used here
}
return init;
}());
这是一个立即执行的函数。在此示例中,我将返回值(init 函数)分配给全局变量,这是脚本将创建的唯一全局变量(只要您使用 var
正确声明它们)。
在 JavaScript: The Good Parts(也总结在这里)中,建议:
全局变量削弱了程序的弹性,应该 避免。最小化全局变量使用的一种方法是创建单个 应用程序的全局变量:
var MYAPP = {};
然后,该变量将成为应用程序的容器:
MYAPP.stooge = { "first-name": "Joe", "last-name": "Howard" };
通过将您的全球足迹减少到一个名称,您可以显着 减少与其他应用程序不良交互的机会, 小部件或库。您的程序也变得更易于阅读 因为很明显,MYAPP.stooge指的是顶级 结构。
- 在 Javascript 中创建全局变量时是否需要指定对象类型
- JSHint是否可以输出有关全局变量的警告
- 检查全局变量是否存在的正确方法是什么
- 确定是否在不使用任何全局变量的情况下加载了窗口
- js事件循环是否意味着可以为临时暂存空间使用全局变量
- 是否可以肯定刷新 $_SESSION[] 全局变量
- 如何在不设置全局变量的情况下确定是否已调用函数
- 对函数内部的全局变量所做的更改是否全局反映?Javascript
- 对角度模块使用单个全局变量是否是一种反模式
- 在 NodeJS 中使用和更新全局变量是否安全?
- 函数是否像局部变量一样适用于全局变量
- Javascript - 全局变量和全局范围内的变量是否不同(在 jsfiddle 中)
- 全局变量存储在 Node.JS 中的什么位置?节点中是否有类似窗口的对象
- 我是否正在创建一个全局变量
- 在Couchbase JavaScript视图中是否有可能的全局变量
- 是否可以将 Ext.Component 声明为全局变量
- 是否有任何选项可以在煎茶触摸中声明全局变量
- 自定义 jquery 函数中的参数是否可以更改全局变量的值
- 检测变量是否为全局变量
- 是否应避免全局变量