JavaScript使用构造函数模式创建的对象避免全局命名空间污染

时间:2015-12-15 11:19:10

标签: javascript design-patterns namespaces

为了创建JS库,我在内部使用构造函数模式创建对象。现在每种类型的对象都在它自己的文件中,所以说book在book.js中。所有文件都连接起来然后缩小。

book.js
--------

function Book (data) {
  this.data = data;
}

Book.prototype.rent = function(name) {
  console.log("Rent the book to " + name);
}

现在一旦加载了包含库的页面,我就会发现从浏览器控制台可以直接创建书籍对象。

var b = new Book("somedata");

我在这里看到2个问题

  1. 全局命名空间的污染,因为Book()对象现在在全局范围内可见。
  2. 安全问题,因为任何人都可以从控制台创建没有名称空间的对象。
  3. 该库实际上位于使用显示模块模式的命名空间下。无论如何,我上面提到的问题是否可以安全处理?无论如何要从全局命名空间(控制台)隐藏对象?

3 个答案:

答案 0 :(得分:2)

您可以做的是您可以在服务器端使用require模块并创建grunt任务以在入口点文件上运行browserify任务,这样您的所有代码都将转换为一个文件,并且无法从全局命名空间访问。结帐http://browserify.org了解更多信息。

答案 1 :(得分:1)

  

任何人都可以从控制台创建没有命名空间的对象的安全问题。

这不是问题,任何人都可以从控制台创建命名空间中的对象。

  

全局命名空间的污染,因为Book()对象现在在全局范围内可见。   该库实际上位于使用显示模块模式的命名空间下。

如果要将所有这些文件作为脚本加载,那么它们会将声明的类放在全局命名空间中。以某种方式使用全局命名空间是不可避免的,但您可以使用显示模块模式立即将所有对象放在该自定义库命名空间上。您需要将每个文件包装在一个将相应类附加到City.Library的IEFE中:

City.Library.Book = (function() {
    function Book (data) {
        this.data = data;
    }
    Book.prototype.rent = function(name) {
        console.log("Rent the book to " + name);
    };
    return Book;
}());

或者,将文件视为模块(首选ES6),让模块加载器/捆绑器自动为您完成此工作。

答案 2 :(得分:0)

你可以将它们封装在闭包中以防止它们脱离全局,但是,这有一个根本问题 - 你希望你的函数/构造函数/ whatevers可以访问!

browserify这样的方法将封装中的文件中的代码包装起来但跟踪它们,以便在需要时可以访问它们。它使用commonJS modules作为访问和组织模块化代码的方法。我建议阅读browserify的文档,因为使用它可以解决这两个问题,虽然它会对你的最终用户强制执行模块系统(我说这通常是一件好事,至少这是一件值得的事情,但是,这是根据您的具体情况决定)

我还应该指出,还有其他编写模块化代码的解决方案,例如webpackjspm