如何在一个真实的例子中使用javascript模块模式?
我想了解JavaScript模块模式。 我已经看到它应该是什么样子的例子,但我不明白如何使用它。
例如,这里发生了一些事情:
$('input#share').on("click", function() { $('.loading').html(''); 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() { ... } }); }
我如何使用上面的例子:
var myTest = function() { var selectId; function addMessage () { // ... } return { // public interface publicMethod1: function () { // all private members are accesible here } }; }; var start = myTest();
我在哪里添加click事件,声明我的vars,使用ajax调用添加addMessage
函数。 并调用addMessage
函数? 我必须在$(document).ready(function()
包装所有内容吗?
任何人都可以为我阐明这一点吗?
谢谢
这是一个很自以为是的主题,但我会这样做(不完全知道你的完整应用程序及其function),有点像:
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(''); 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();
你的模式的原始代码是错误的,函数必须在最后有()
,使它成为一个立即调用的函数,然后执行,通过return statement
公开任何东西。
你可能希望与我所做的略有不同,这只是一个基本的想法,但我希望它可以让你开始。
有一段时间回答了一个与这种模式有关的问题, 我回答了它解释了我们使用的原因(function() {})();
以及return
语句如何在该上下文中起作用,如果您对它有点困惑,那也可能值得一读。
显示模块模式使用如下:
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'); } }; }());
您还可以将公共变量/方法定义为私有,然后公开对它们的引用,使它们公开。 这是一个偏好的问题。
在您的示例中,如果您希望addMessage
成为模块的一部分,您可以这样做:
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();
我有一些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”对象公开我想要的方法,所以(我猜)没关系。 但我是一个新手,这看起来很简单,(乍一看)优雅,我必须错过一个主要问题。 它与Object Literal格式共享编码风格,这是我从Mootools熟悉的。 所以也许我正试图将一个圆形钉固定在一个方孔中。 也许内部对象文字不是必需的,因为我可以说“doSomething”而不是“self.doSomething()”。 是这样的吗?
部分我喜欢这个因为我可以将$ .ajax的“context”参数设置为“self”,这似乎是一个胜利。
我们的想法是通过将代码划分为段/模块来降低外部世界的可见性和更好的代码管理。如果您希望看到模块化设计模式的真正良好使用以及我们如何从中获益的一些方法,请查看它。
http://learn.jquery.com/code-organization/concepts/
与JAVA不同,Javascript没有私有和公共属性或方法的概念。 让我们创建一个名为person的对象,它有2个属性firstName和lastName,还创建了2个函数,它们将是我们属性的getter。 在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。 嗯,这对于面向对象的编程来说并不好。 好吧,我们成功实现了getter,所以我们也应该有公共范围的setter,属性应该标记为私有范围(这些私有和公共概念属于JAVA,C ++类似于语言)。 我们的意图很好,让我们应用特定于Javascript的概念。 我们不想做person.firstName,我们希望直接阻止属性的访问。 在像JAVA这样的语言中,由于私有和公共,我们实现了属性的受控控制,但在Javascript中,一切都是公开的。
Javascript使用闭包的概念来实现私有和公共之类的东西。 此模式称为模块模式。 也就是说,隐藏变量来自公共访问。 为了实现范围,请将代码包装在函数中(请记住,范围是通过Javascript中的函数实现的)。
function createPerson(){ var returnObj={ "firstName":"Anoop", "lastName":"Rai", "getFirstName":function(){ return this.firstName; }, "getLastName":function(){ return this.lastName; } }; return returnObj; } var person=createPerson(); console.log(person.getFirstName()); console.log(person.firstName);
现在上面的线条印有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);
现在上面的行打印Anoop和undefined。 这是怎么发生的? 由于闭包,在创建函数getFirstName和getLastName时,函数具有整个作用域链或指向相关变量的指针,即firstName和lastName。 对象returnObj不记得变量,但由于闭包,函数对象会记住这些变量。 看起来我们已经实现了我们想要的东西,但有一件事是剩下的,那就是firstName和lastName的受控访问的setter。 让我们实现setter。
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());
我们成功修改了firstName但是以受控方式。
http://jkoder.com/the-module-pattern-javascript-way-of-hiding-data-in-objects-from-public-access/