如果目标是避免污染全局范围,为什么没有更多人将其全局命名空间对象随机化?

时间:2014-08-24 00:14:02

标签: javascript

这里真正的危险是什么?它似乎没有加起来 - 我错过了什么?在阅读了RequireJS文档和Addy Osmani的设计模式(模块部分)之后 - 似乎大多数人都没有问题返回一个静态的,预定义的对象名来创建他们的app / plugin / module的命名空间。

我可以看到我们不想等待所有其他脚本加载以定义我们自己的脚本,但除此之外...只要我将应用程序的所有代码放入少数全局名称间隔对象中尽可能......重要吗?

1 个答案:

答案 0 :(得分:2)

对于图书馆,您需要为您的用户(有时是您自己)提供某种方式来使用它。因此,让我们尝试将其作为随机实验:

我创建了一个很酷的库,可以让您在网站上添加3D实时聊天功能。该库的名称空间是随机的。不,我不会告诉你它是什么,它是随机的。您可以以任何您喜欢的方式使用它,因为我已经在自由的知识共享许可下许可了它。

现在这对你来说是一个挑战。使用我的图书馆。

什么?你想让我提供文件吗?好的,确定:

  

要启动3D聊天,请调用init()函数,如下所示:????。init()。注意:替换????具有适当的库名称空间。不,我不会告诉你它是什么,因为我不知道它:它是随机的。是的,每当有人加载页面时它都会改变。

如果不知道命名空间是什么,你就可以真正使用该库。

我可以使它更简单,并且具有稍微更结构化的命名空间。让它给它一个Chat3D_????的命名空间,其中????将始终替换为4位数的随机数(您知道,以避免污染全局范围)。

要使用此版本的库,您必须执行以下操作:

for (var i = 1111; i < 9999: i++) {
    if (window['Chat3D_' + i]) {
        window['Chat3D_' + i].init();
        break;
    }
}

现在这很愚蠢。


如果您的代码不是库,意味着没有其他用户会调用它(甚至不是您自己),那么javascript已经提供了比随机变量名更好的机制,以避免污染全局范围:IIFE:

(function(){

    // all your code go here

})();

因此,其他一些代码需要使用您的代码。在这种情况下,您应该提供全局引用(最好只提供一个全局引用 - 即命名空间)。或者没有其他代码需要使用您的代码。在这种情况下,您可以隐藏闭包内的所有内容。

没有随机命名空间有意义的用例。


补充答案:

Node.js向我们展示了另一种完全避免污染全局范围但允许您使用库的方法:节点模块允许您(用户)选择命名空间的名称:

var my_custom_namespace_for_3D_chat = require('3Dchat');

请注意,从可用性的角度来看,实现3Dchat模块不应该要求作者创建随机变量名称。然而,我承认可以用随机全局变量实现这样的模块特征。虽然这不是我选择的实现。尽管如此,从普通程序员的角度来看,图书馆作者和图书馆用户都不应该随机化模块的名称/命名空间。这是模块系统的工作(有点像在将C ++编译为C的旧实现中的C ++变量名称修改)。

但是,这根本没有解决名称冲突的问题。是的,您可以完全避免全局变量名称冲突,但仍然存在模块名称冲突。另一个人无法创建另一个名为'3Dchat'的库,并希望使用相同的require语句。