代码之家  ›  专栏  ›  技术社区  ›  Matthew Murdoch

我应该如何定义一个JavaScript“名称空间”来满足JSLint?

  •  20
  • Matthew Murdoch  · 技术社区  · 14 年前

    JSLint (使用“好零件”选项)。

    Advanced JavaScript (不带YUI的节名称空间):

    "use strict";
    if (typeof(MyNamespace) === 'undefined') {
        MyNamespace = {};
    }
    

    把这个弄清楚 JSLint公司 给出以下错误:

    Problem at line 2 character 12: 'MyNamespace' is not defined.
    Problem at line 3 character 5: 'MyNamespace' is not defined.
    Implied global: MyNamespace 2,3
    

    “隐含全局”错误可以通过显式声明 MyNamespace

    "use strict";
    if (typeof(MyNamespace) === 'undefined') {
        var MyNamespace = {};
    }
    

    …另外两个错误可以通过在if块外声明变量来修复。

    "use strict";
    var MyNamespace;
    if (typeof(MyNamespace) === 'undefined') {
        MyNamespace = {};
    }
    

    所以这是可行的,但在我看来 我的命名空间 在检查时总是未定义?)它相当于更简单的:

    "use strict";
    var MyNamespace = {};
    

    满足于此,但我担心的是,我已经将代码简化到这样的程度,它将不再作为命名空间正常工作。这最后的公式合理吗?

    6 回复  |  直到 14 年前
        1
  •  19
  •   bobince    14 年前

    不要把杰斯林特的话当作福音。它所说的大部分是明智的,但它也附带了克罗克福德的个人教条很多。尤其是我并不总是同意他说的 var

    "use strict";
    if (typeof(MyNamespace) === 'undefined') {
        MyNamespace = {};
    }
    

    那个不好;JSLint抱怨隐含的全局错误是正确的。 'use strict'

    "use strict";
    if (typeof(MyNamespace) === 'undefined') {
        var MyNamespace = {};
    }
    

    是这样吊起来的 MyNamespace 存在并设置为 undefined 输入代码块时。所以你可以做这个测试 (MyNamespace===undefined) 即使没有 typeof

    另一种方法是使用明确的 in 运算符(这是区分不存在的属性和设置为的属性的唯一方法) ). 对于普通浏览器脚本中的globals,您可以对global脚本使用它 window 对象:

    'use strict';
    if (!('MyNamespace' in window)) {
        window.MyNamespace = {};
    }
    

    (JSLint也不喜欢这样,因为假设浏览器似乎没有定义 窗口

        2
  •  7
  •   Ryan    13 年前

    您可以尝试更短的版本:

    var MyNamespace = MyNamespace || {};
    

        3
  •  6
  •   George Stocker NotMe    10 年前

    这是一个非常老的问题,但我想我无论如何都会回答,因为上面没有一个为我清除jslint的所有错误,因为我怀疑lint'r已经更新了:-)

    也许还有其他方法可以做到这一点,但截至2013年,这是我能想到的最好的方法

    如果您想要一个无错误的jsLint模块模式,它有一个名称空间和严格的

    this.ns = this.ns || {}; // Check for global namespace and if not found create 
    
    (function(ns) {
      'use strict'   // restrict usage to this module 
    
      ns.myFunction = function() {
      } 
    
    } (this.ns)); // Pass in the global namespace you 'might' have created above and 
                  // drop 'this' reference
    

    “this”是避免范围外错误的必要条件(看起来不重要,但我猜使用“this”是显式的,而仅仅使用ns或var ns都会抛出错误。

    当然,其他工具不喜欢将“this”作为一个不确定的参数来警告它是全局的(当然这是目的),所以。。。番茄

        4
  •  3
  •   Amber    14 年前

    您可以通过 window["NAMEOFGLOBAL"]

    if(typeof(window['MyNamespace']) === 'undefined') {
    
        5
  •  1
  •   spender    14 年前

    当然,未定义检查的重点是确保用户不会重复加载或覆盖现有的命名空间。因此,我认为你做得太过分了。

    怎么样:

    var MyNs;
    if(MyNs==null){
        //foo()
    }
    
        6
  •  1
  •   Jimmy Nitzan Tomer    14 年前

    我以前遇到过这个问题。您肯定不想使用final表单,因为它完全绕过了对已定义变量的检查,并且总是将其覆盖为空对象,即使其中已经存储了内容。

    我认为倒数第二个表单最适合创建名称空间,但实际上第一个表单也不错。JSLint报告的错误在我看来有点像第二十二条军规,不需要太担心。我认为省略声明不是什么大问题的原因是,在命名空间