在Javascript中这是什么样的模式/对象?

时间:2009-10-31 00:34:02

标签: javascript

我看到了很多这种模式(我实际上使用过),但我想要解释它是如何工作的。

var mystuff = function() {


    var blah = function() {

    };


    return {

        setup: function() {
              blah();
        };

    };


}();

然后使用非常像OOP:

mystuff.setup();

6 个答案:

答案 0 :(得分:6)

正在做的是返回对象的公共接口。您似乎正在使用公共setup()函数来访问私有blah()函数。这是在Javascript对象中模拟公共和私有成员函数的一种方法。

由于mystuff在底部定义了尾部(),因此当解析器到达mystuff.setup()时会立即执行,并实际返回一个带有{的匿名对象(您的公共接口) {1}}方法。

答案 1 :(得分:6)

其他人已经解释了它是如何运作的。这只是关于该主题的更多背景信息。

它被称为"Module pattern"(由Douglas Crockford创造,我相信,但有关earlier的博客。)

它为您带来三个主要好处:

  1. 命名空间("function"左侧的值)
  2. 一个私有的“空间”,用于放入(变量,函数等)不需要或不应该污染全局命名空间的东西(这是return语句之前的内容)
  3. 一个公共“空间”,用于放置您希望可供命名空间用户访问的内容(这是return语句)
  4. 所有这些都是一种可读的形式。

答案 2 :(得分:2)

这只是JavaScript中nested functions的一个示例。虽然调用它们的方法在表面上可能看起来像“类似OOP”,但这种风格非常属于functional paradigm

然而,从本质上讲,没有什么太花哨的了。 JavaScript被称为“一切都是函数”的语言,它与事实非常接近。所有这意味着声明的任何函数都严格属于其父作用域。

答案 3 :(得分:0)

它是从函数式编程方法到面向对象编程。外部(匿名)函数(构造函数)中的局部变量可供构造函数中定义的任何函数访问,但不能在其他地方访问,从而使局部变量保持私有。它与纯函数方法的不同之处在于构造函数返回一个对象文字而不是另一个函数。内部函数可以访问局部变量,因为它被称为closure

它的用途是创建私人领域&方法,以局部变量的形式。

答案 4 :(得分:0)

  

但我想解释它是如何运作的。

让我们一块一块地去除它。

function() { .... }是匿名函数的语法 function() { .... }()定义并在同一行上调用匿名函数。

示例中函数的返回值是使用JSON表示法定义的对象(Javscript对象表示法)

{ setup : .... }是一个具有一个属性的对象:它被称为setup,在您的情况下恰好是一个函数。

所以,mystuff得到了返回值,这是一个名为setup的属性(函数)的对象,而mystuff.setup()调用了这个setup函数。

现在,有趣的部分可能是setup只调用blah函数,它是在包含匿名函数的内部定义的。

我认为此处的技术术语是closure(请参阅forming closures部分)(另请参阅wikipedia定义)

本质上,函数变得像它自己的模块,变量绑定到它。

crescentfresh's answer

中对此进行了解释

答案 5 :(得分:0)

首先,请避免使用以下语法:

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

这是不好的编码实践,因为它不是完全跨浏览器,因为一些浏览器会在这里出错。 习惯于在函数周围添加括号:\

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

接下来,关于模式。这种模式在JavaScript中通常简称为“ encapsulation ”。闭包是另一种可能,但更具体地说,在这种情况下它纯粹是封装

封装只是意味着你让一些成员变得私密。在这种情况下私人是什么? 在这种情况下,blah变量是私有的。请养成私人会员以下划线表示他们是私人的习惯。将公共方法与私有方法区分为下划线是一种很好的编码实践。

<script type="text/javascript">
var obj=(function(){
    //private members
    var _p={};//toss all private members into a single object.
    _p.list=[];
    _p.init=function(){
        _p.list=[];
    };

    //public members. use "this" to reference object followed by the method.
    //however obj._p.list won't be accessible to the global scope
    return {
        reset:function()
         {
            _p.init();
         }
        ,addName:function(str)
         {
            _p.list.push(''+str);//limit to strings
         }
         ,getNames:function()
          {
            return _p.list.slice(0);//return a clone
          }
         ,alertNames:function()
          {
            alert(this.getNames().join(","));
          }
         ,getPrivateObj:function()
          {
            return _p;
          }
    };
})();

obj.alertNames();
obj.addName("Nandan");
obj.addName("Ram");
obj.alertNames();
obj.reset();
obj.alertNames();
obj.addName("Vinoth");
obj.addName("Kevin");
obj.alertNames();
alert(typeof obj._p);//undefined
var privateObj=obj.getPrivateObj();
alert(typeof privateObj);
alert(privateObj.list.join("|"));
</script>