如何重构js中的全局变量

339 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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;
}

来看看测试结果:

image.png

可以看到:

APP.namespace(‘APP.modules.module1’)

上面的代码给出了所期望的结果,并且传递app(命名空间中的顶级全局对象)也是多余的。我们可以仅仅传递odules.module1来实现同样的效果.

APP.namespace(‘modules.module1’)

总结:

我们应该尽可能减少全局变量的使用,本文给出了一个已命名空间重构消除代码中全局变量的一个方案.

译自: javascript.plainenglish.io/how-to-refa…