定义和立即调用匿名函数如何解决命名空间问题?

时间:2014-02-11 04:46:26

标签: javascript

我正在阅读this page,其中包含:

myNameSpace = function(){
  var current = null;
  function init(){...}
  function change(){...}
  function verify(){...}
  return{
    init:init,
    change:change
  }
}();
     

我只返回指针而不是返回属性和方法   给他们。这样可以轻松调用函数和访问变量   来自其他地方而无需通过myNameSpace名称。

但我不明白这是怎么回事。您仍需myNameSpace.init()拨打init。仅init()不起作用。

编辑:我后来发现,也许作者意味着他们能够在匿名函数中无需资格来调用init()。但令我感到困惑的是,作者之前的例子已经能够做到这一点。具体而言,在前面的例子中:

myNameSpace = function(){
  var current = null;
  function verify(){...}
  return{
    init:function(){...}
    change:function(){...}
  }
}();

他/他定义init作为他/她正在返回它,而不是上面的示例,其中他/她首先定义init然后返回指向它的指针。但是在前面的例子中,在匿名函数中,如果你想在不必init()的情况下调用myNameSpace.init(),你就可以。那么引用的例子如何更好?。

有人可以解释一下吗?感谢。

2 个答案:

答案 0 :(得分:2)

使用函数清理范围的想法是,假设您有一个如下所示的程序:

var number = 10;
var multiplier = 2;
var endingText = " days left!";
var string = (10 * 2) + endingText;
// string is "20 days left!"

这是一个非常人为的例子,但希望很明显,这将在全球范围内宣布四个变量,这是非常可怕的。让我们说你真正想要的是string,但你仍然想要保留其他三个变量,无论出于何种原因。您可以将它们放在匿名函数中,如下所示:

var string;
(function(){
  var number = 10;
  var multiplier = 2;
  var endingText = " days left!";
  string = (10 * 2) + endingText;
})();
// string is still "20 days left!"

因为变量是函数范围的,所以numbermultiplierendingText未在全局范围内声明。但是,您仍然可以使用它们来获得您想要的结果。

顺便说一下,如果你想立即调用它,你需要在函数周围包裹parens。此外,您不应该将此与命名空间混淆。 JavaScript中的命名空间是为对象的属性分配有意义的值的想法。

var foo = {
  hello: "goodbye",
  frank: "bob"
};

hellofrankfoo命名空间中声明。这里的所有都是它的。您发布的示例使用命名空间概念并立即调用函数概念来清理变量。

答案 1 :(得分:1)

措辞有点令人困惑。他的意思是说:

  

现在可以轻松访问函数和变量,而无需模块

中的命名空间

- 与对象文字模式或前一个示例相反,他将公共方法直接放在导出的对象上。当然,从外部你总是需要将它们作为命名空间对象的属性来访问 - 这就是使其成为命名空间的全部要点: - )

举个例子,让我们用一些最小的代码填充函数:

myNameSpace = function(){
  var current = null;
  function verify(…){…}
  return {
    init:function(el){
      el.addEventListener("input", myNameSpace.change, false);
      //                           ^^^^^^^^^^^^^^^^^^
    },
    change:function(){
      if (!verify(this.value)) alert("wrong");
    }
  }
}();
myNameSpace.init(document.getElementById("testInput"));

VS

myNameSpace = function(){
  var current = null;
  function verify(…){…}
  function change(){
    if (!verify(this.value)) alert("wrong");
  }
  function init(el){
    el.addEventListener("input", change, false);
    //                           ^^^^^^
  }
  return {
    init:init,
    change:change
  }
}();
myNameSpace.init(document.getElementById("testInput")); // no difference here

在这个例子中差异可能很小,但是当你有很多相互引用的功能时,它就很重要了。此外,您将知道所有本地的无名称空间函数都属于当前模块,这在处理许多不同的名称空间时大大提高了可维护性。