我应该在window.document中放置变量还是使用全局上下文?

时间:2013-04-22 11:57:18

标签: javascript api

我有一个变量 api ,其中我想要在 test 变量中使用更多方法,并且两者都在全局上下文中。

我认为如果将它们放在window.document上会更好,我想知道其他选项是什么。

var api = (function(){

  this.run= function(){
    console.log("run api");
  };

  return this;

})();

// test在单独的文件中

var test = (function(one_){

  this.as = function(){
    console.log(one_.run());
  };


  return this;

})(one);


test.as();

3 个答案:

答案 0 :(得分:4)

var company = company || {} ;

company.doSomething = function() {
};

company.test = {};
company.test.submodule = {};
company.test.submodule.doSomething = function() {};

company.api = {};
company.api.submodule = {};

通常应避免全局定义变量。对于清晰的可维护代码,请将对象用作名称空间,并避免污染全局名称空间。

这也极大地增强了默认的JS功能。如果您非常热衷于此,请在项目中添加require.js等内容,您将获得非常好的类似Java的功能。

因此,对于require.js,您的company.apicompany.test可以放在不同的文件中,require可以放在一起,就像您使用import company.test一样一个Java package

命名空间是一种非常有效的做法。你得到:

  1. 可读性(世界上最重要的事情!!)。
  2. 可维护性。
  3. 调试速度更快。
  4. 升级速度更快。
  5. 有效划分逻辑和功能。
  6. 防止IE windowglobal对象错误。
  7. 让团队合作愉快而愉快。
  8. 加快开发很多。大多数IDE将索引和自动填充命名空间对象。
  9. 您可以有效地使用jsDoc标记来记录您的JavaScript代码。
  10. 重要

    在静态上下文中使用this也相当危险。 JavaScript命名约定规定static将以小写字母char开头,类将以大写字母char开头,当然使用camelCase。

    再次,一个非常强大和有用的约定。它告诉开发人员,眨眼之间某些东西是静态的或类。例如,如果你有:

    company.test.submodule.doSomething = function() {
        // this is a static function. It's a normal property, it's not nested under the prototype.
    };
    

    相反,如果你想创建一个类,你可以用正确的方式使用this引用。

       // Notice Person starts with uppercase P.
    company.test.subModule.Person = function(name) {
        this.name = name;
        this.numberOfEyes = 2;
    };
    company.test.subModule.Person.prototype.cryMeARiver = function() {
        console.log(this.name + " can cry a river.");
    };
    

    现在在其他任何功能中,您可以这样做:

    company.api.someSubModule.peopleCryRivers = function() {
        // this is again a static context.
        var bodgan = new company.test.subModule.Person("Bogdan");
        var andreea = new company.test.subModule.Person("Andreea");
        bodgan.cryMeARiver();// will output "Bogdan can cry a river."
        andreea.cryMeARiver();// will output "Andreea can cry a river."
        // etc..
    };
    

答案 1 :(得分:2)

在全局命名空间(即window)和window.document中删除内容之间没有什么区别。

有时候(特别是从多个源模块访问变量时)你只需 来创建一个全局变量,所以当你这样做时,使用命名空间封装你的变量,让命名空间本身成为唯一泄露的变量:

第1单元:

var BOGDAN = BOGDAN || {};
BOGDAN.api = ...

第2单元:

var BOGDAN = BOGDAN || {};
BOGDAN.test = ...

答案 2 :(得分:1)

将变量附加到window.document对我没有意义,而将它们附加到window与在全局命名空间中声明相同。

您可以创建(全局)变量作为命名空间,并将其他变量附加到此。

var APP = {};
APP.api = ...

这当然会冒与另一个名为'APP'的对象发生冲突的风险。

另一种选择是简单地将变量包装在立即调用的函数表达式中。

(function() {
    var api = ...
}();

这将把它们限制在IIFE中,它们不会产生冲突。这也意味着当您的变量超出范围时,它们将有资格进行垃圾收集。