如何在实际示例中使用javascript模块模式?

如何在实际示例中使用javascript模块模式?,javascript,jquery,design-patterns,module-pattern,Javascript,Jquery,Design Patterns,Module Pattern,我试图理解JavaScript模块模式。我看到过它应该是什么样子的例子,但我不知道如何使用它 例如,这里发生了一些事情: $('input#share').on("click", function() { $('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />'); var message = $(".wallmessage").val(); if (m

我试图理解JavaScript模块模式。我看到过它应该是什么样子的例子,但我不知道如何使用它

例如,这里发生了一些事情:

$('input#share').on("click", function() {

    $('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');

    var message = $(".wallmessage").val();

    if (message == ""){
        $("#messageempty").jmNotify();
        $('.remove_loading').remove();
    } else {
        addMessage(message);
    }

    return false;
});


function addMessage(message)
{
    $.ajax({
        url: '/test',
        type: 'POST',
        dataType: "json",
        data: {'message' : message},
        success: function(data) {
                ...
        },
        error: function() {
            ...
        }
    });
}
我应该在哪里添加click事件、声明我的vars、使用ajax调用添加
addMessage
函数。并调用
addMessage
函数?我是否必须将所有内容包装在
$(document).ready(function()
)中

有人能帮我解释一下吗


谢谢

显示模块模式的使用方式如下:

var moduleName = (function () {
    var privateVariable = 'private';

    var privateMethod = function () {
        alert('this is private');
    };

    // this is the "revealed" part of the module
    return { 
        publicVariable: 'public',
        publicMethod: function () {
            alert('this is public');
        }
    };
}());
var moduleName = (function () {
    // this becomes public due to the reference exposure in the return below
    var addMessage = function () {
        // do whatever
    };

    // this is the "revealed" part of the module
    return { 
        addMessage: addMessage
    };
}());

moduleName.addMessage();
您还可以将公共变量/方法定义为private,然后公开对它们的引用,将它们公开。这是一个偏好问题

在您的示例中,如果希望
addMessage
成为模块的一部分,您可以这样做:

var moduleName = (function () {
    var privateVariable = 'private';

    var privateMethod = function () {
        alert('this is private');
    };

    // this is the "revealed" part of the module
    return { 
        publicVariable: 'public',
        publicMethod: function () {
            alert('this is public');
        }
    };
}());
var moduleName = (function () {
    // this becomes public due to the reference exposure in the return below
    var addMessage = function () {
        // do whatever
    };

    // this is the "revealed" part of the module
    return { 
        addMessage: addMessage
    };
}());

moduleName.addMessage();

这是一个相当固执己见的话题,但我会这样做(不完全了解您的完整应用程序及其功能),有点像这样:

var myApp = (function() {

  var someElement = $("#foo"); //some element I know I'll use lots

  var addMessage = function(message) {
    $.ajax({
      url: '/test',
      type: 'POST',
      dataType: "json",
      data: {'message' : message},
      success: function(data) {
              ...
      },
      error: function() {
          ...
      }
    });
  };

  var inputClick = function(event) {
    event.preventDefault();
    //depending on if you'll reuse these selectors throughout the app I might have these as variables
    $('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');

    var message = $(".wallmessage").val();

    if (message == ""){
      $("#messageempty").jmNotify();
      $('.remove_loading').remove();
    } else {
      addMessage(message);
    }
  };

  var bindFunctions = function() {
    $("input#share").on("click", inputClick)
  };

  var init = function() {
    bindFunctions();
  };

  return {
    // EDIT: 27/12/16 - need to return init for 'usage' example to work
    init: init,
    addMessage: addMessage
    //anything else you want available
    //through myApp.function()
    //or expose variables here too
  };


})();

//usage

myApp.init();
var myApp=(函数(){
var someElement=$(“#foo”);//一些我知道我会使用的元素
var addMessage=函数(消息){
$.ajax({
url:“/test”,
键入:“POST”,
数据类型:“json”,
数据:{'message':message},
成功:功能(数据){
...
},
错误:函数(){
...
}
});
};
变量inputClick=函数(事件){
event.preventDefault();
//根据你是否会在整个应用程序中重用这些选择器,我可能会将它们作为变量
$('.loading').html('');
var message=$(“.wallmessage”).val();
如果(消息==“”){
$(“#messageempty”).jmNotify();
$('.remove_loading').remove();
}否则{
添加消息(message);
}
};
var bindFunctions=函数(){
$(“输入共享”)。在(“单击”,输入单击)
};
var init=函数(){
bindFunctions();
};
返回{
//编辑:27/12/16-需要返回init以使“用法”示例正常工作
init:init,
addMessage:addMessage
//还有什么你想要的吗
//通过myApp.function()
//或者在这里公开变量
};
})();
//用法
myApp.init();
模式的原始代码是错误的,函数的最后必须有
()
,使其成为一个立即被调用的函数,然后执行,通过
返回语句暴露任何内容

您可能希望与我所做的略有不同,这只是一个基本的想法,但我希望它能让您开始


不久前有人问了一个与此模式相关的问题,并解释了我们为什么使用
(function(){})()
以及
return
语句在该上下文中的工作原理,如果您对此有点困惑,那么这可能也值得一读。

我对Mootools有一些经验,但我是jQuery新手。我已经阅读了文档,看起来组织代码的最聪明的方法是模块模式,所以我正在尝试。然而,这种风格似乎缺少了“自我”的概念,因为IIFE中的每个变量都是一个自包含的对象(没有双关语)

所以…也许这违背了整个目的,但是你能做一些像这样的事情,并且仍然让它在模块模式样式有效的所有方面都“有效”吗

var feature = ( function () {

    var self = {

        config: {
            option1: 'thing 1',
            option2: 'thing 2'
        },


        init: function (options) {

            // allow overriding the default config
            jQuery.extend( self.config, options );

            self.doSomething();

        },

        doSomething: function () {

        },

    };

    return {
        init: self.init
    }

})();
我喜欢的是,我可以使用“self”在内部引用所有的方法和属性。我仍然能够使用“return”对象公开我想要的方法,所以(我想)没关系。但是我是一个新手,这看起来很简单,而且(乍一看)优雅,我一定错过了一个主要的问题。它与对象文字格式共享编码风格,这是我在Mootools中熟悉的格式。因此,也许我正在尝试将一个圆钉装入一个方孔中。也许内部对象文字不是必需的,因为我可以说“doSomething”,而不是“self.doSomething()”是这样吗


部分原因是我可以将$.ajax的“context”参数设置为“self”,这似乎是一个胜利。

我们的想法是通过将代码划分为段/模块来降低外部世界的可视性和更好的代码管理。如果您想看到模块化设计模式的真正良好使用以及我们如何从中获益,请查看此内容。

与JAVA不同,Javascript在属性或方法上没有私有和公共的概念。让我们创建一个名为person的对象,它有两个属性firstName和lastName,还创建了两个函数作为属性的获取程序。在Javascript中,我们可以创建函数作为对象的属性&这些函数是与任何其他财产一样,在任何地方都可以访问

var person={
  "firstName":"Anoop",
  "lastName":"Rai",
  "getFirstName":function(){
    return this.firstName;
  },
  "getLastName":function(){
    return this.lastName;
  }
};
console.log(person.getFirstName());
console.log(person.firstName);

以上代码11打印Anoop和ANOOP。HMM,这对于面向对象编程不好。我们成功地实现了GETTES,因此我们也应该有公共范围的设置器,并且属性应该被标记为私有范围(什么??这些私有和公共概念属于java、C++类语言)。。我们的意图是好的,让我们应用特定于Javascript的概念。我们不想使用person.firstName,我们希望直接阻止对属性的访问。在像JAVA这样的语言中,由于私有和公共的原因,我们实现了对属性的受控访问,但在Javascript中,一切都是公共的

Javascript使用闭包的概念来实现私有和公共之类的东西。这种模式称为模块模式。也就是说,对公共访问隐藏变量。为了实现作用域,请将代码包装在函数中(记住,作用域是通过Javascript中的函数实现的)

现在上面的几行也打印了Anoop和Anoop。仍然没有成功。只要属性绑定到对象,它就会被直接访问。让我们解开它。我们用函数范围的变量(闭包变量)代替属性

现在越过线
function createPerson(){
  var firstName="Anoop";
  var lastName="Rai";
  var returnObj={
    "getFirstName":function(){
      return firstName;
    },
    "getLastName":function(){
      return lastName;
    }
  };
  return returnObj;
}
var person=createPerson();
console.log(person.getFirstName());
console.log(person.firstName);
function createPerson(){
  var firstName="Anoop";
  var lastName="Rai";
  var returnObj={
    "getFirstName":function(){
      return firstName;
    },
    "getLastName":function(){
      return lastName;
    },
    "setFirstName":function(name){
      return firstName=name;
    },
    "setLastName":function(name){
      return lastName=name;
    }
  };
  return returnObj;
}
var person=createPerson();
console.log(person.getFirstName());
person.setFirstName("Kumar");
console.log(person.getFirstName());