一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情
我们都听说或读到过,全局变量是不好的做法。用多个全局变量污染代码空间会导致无法管理和不可预测的代码。 始终建议控制全局变量,并尽可能将其降至最低。 在本文中,我们将讨论一种可以轻松减少全局变量的方法。 假设在您的代码库中存在以下全局变量:
// Constructors
function X() {}
function Y() {}
// global vars
var res = 1;
// global objects
var module1 = {
a: 1,
b: 2
};
var module2 = {};
module2.a = 10;
module2.b = 20;var module3 = {};
在上面的模块中,我们有6个全局变量。现在,我们可以重构这段代码,使其只有一个全局对象,所有的构造函数、变量和对象都将是它的一个属性。 理想情况下,所有代码库都应该只有一个全局变量。有多个全局变量是不好的, 它们可能会被意外修改,并且容易出错。 此外,它可能会导致与第三方库或代码冲突.
解决方案
重构后的代码
// Global object
var APP = APP || {};
// Constructors
APP.X = function () {};
APP.Y = function () {};
// variables
APP.res = 1;
// objects
APP.modules.module1 = {a: 1, b: 2};
APP.modules.module2 = {};
APP.modules.module2.a = 10;
APP.modules.module2.b = 20;
APP.modules.module3 = {};
上面代码存在的问题,如果您想使用以下代码:
var module1 = APP.modules.module1;
您必须进行如下3项检查:
var module1 = APP && APP.modules && APP.modules.module1;
这有点烦人。
为了解决这个问题,我们需要一个函数来处理命名空间部分。让我们称这个函数为“namespace()”,并像这样使用它:
APP.namespace(‘APP.modules.module1’)
相当于:
var APP = {
modules: {
module1: {
}
}
};
namespace()函数的实现
var APP = APP || {};
APP.namespace = function (str) {
var parts = str.split('.'),
parent = APP;
// remove the redundant global
if (parts[0] === 'APP') {
parts = parts.slice(1);
}
for (var i = 0; i < parts.length; i++) {
if (typeof parent[parts[i]] === 'undefined') {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
}
来看看测试结果:
可以看到:
APP.namespace(‘APP.modules.module1’)
上面的代码给出了所期望的结果,并且传递app(命名空间中的顶级全局对象)也是多余的。我们可以仅仅传递odules.module1来实现同样的效果.
APP.namespace(‘modules.module1’)
总结:
我们应该尽可能减少全局变量的使用,本文给出了一个已命名空间重构消除代码中全局变量的一个方案.