Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对象文字或模块化Javascript设计模式_Javascript_Jquery - Fatal编程技术网

对象文字或模块化Javascript设计模式

对象文字或模块化Javascript设计模式,javascript,jquery,Javascript,Jquery,这可能已经被问了很多次了,我已经四处搜索过了,但到目前为止,我读到的所有答案都不是我想要的 我正在开发一个具有适度DOM元素的网站,其中包括显示/隐藏、一些AJAX调用,可能还有其他内容。因此,我将有两个主脚本文件(HTML5样板文件标准) 以前我使用的是对象文字设计模式,所以我的site.js是这样的: var site = { version: '0.1', init: function() { site.registerEvents(); }, registerEv

这可能已经被问了很多次了,我已经四处搜索过了,但到目前为止,我读到的所有答案都不是我想要的

我正在开发一个具有适度DOM元素的网站,其中包括显示/隐藏、一些AJAX调用,可能还有其他内容。因此,我将有两个主脚本文件(HTML5样板文件标准)

以前我使用的是对象文字设计模式,所以我的
site.js
是这样的:

var site = {
  version: '0.1',
  init: function() {
    site.registerEvents();
  },
  registerEvents: function() {
    $('.back-to-top').on('click', site.scrollToTop);
  },
  scrollToTop: function() {
    $('body').animate({scrollTop: 0}, 400);
  }
};

$(function() {
  site.init();
});
到目前为止还不错,它可读性很好,所有方法都是公共的(我有点喜欢这样,因为我可以在必要时通过Chrome开发工具直接测试它们)。然而,我打算将网站的一些功能解耦为更模块化的风格,因此我希望在上面的代码下面(或在单独的文件中)有类似的内容:

正如你所看到的,它是非常可读的。但是有一个明显的缺点,那就是我必须编写类似于
site.auth.doms.loginButton
site.auth.events.onLoginButtonClicked
的代码。突然间,它变得难以阅读,而且功能越复杂,它只会变得越长。然后我尝试了模块化模式:

var site = (function() {
  function init() {
    $('.back-to-top').on('click', scrollToTop);
    site.auth.init();
  }

  function scrollToTop() {
    $('body').animate({scrollTop: 0}, 400);
  }

  return {
    init: init
  }
})();

site.auth = (function() {
  var doms = {
    loginButton: $('.login'),
    registerButton: $('.register')
  };

  function init() {
    doms.loginButton.on('click', onLoginButtonClicked);
  }

  function onLoginButtonClicked() {

  }

  return {
    init: init
  }
})();

// more modules

正如您所看到的,这些长名称已经不存在了,但是我想我必须初始化site.init()函数中的所有其他模块来构造它们?然后我必须记住返回其他模块需要访问的函数。虽然有点麻烦,但总的来说,这两种模式都可以,但我是否使用了更好的模块化工作流程?

正确的答案当然是:“这取决于”

如果您对所有数据和所有方法都完全满意,并且站点的每个部分都是100%公开的,那么只要使用一个文本(或多个文本)和嵌套对象(如果需要)就完全可以了,假设您可以防止它变成一个巨大的代码球

如果您想要任何类型的私有状态,它具有任何类型的持久性(即:不会在每次运行函数时重置),那么显示模块非常棒

也就是说:
显示模块根本不要求您具有
.init
方法。
如果您的模块可以是自包含的,那么只需将重点放在导出您想要公开的内容上

为此,当我编写团队稍后可能会查看的代码时,我发现自己创建了一个
public\u接口
对象并返回它(返回的匿名对象的命名版本)

这样做的好处微乎其微,只是增加了一个理解,即任何需要公开的内容都需要附加到接口中

您当前使用它的方式:

var module = (function () { /* ... */ return {}; }());

module.submodule = (function () { /*...*/ return {}; }());
不比文字更好也不比文字更差,因为您可以同样轻松地做到这一点:

var module = {
    a : "",
    method : function () {},
    meta : { }
};

module.submodule = {
    a : "",
    method : function () {},
    meta : { }
};
在你遇到不适合你的事情之前,用满足你需要的东西来工作

就个人而言,我通常会将任何纯数据对象构建为文本:配置对象、来自其他连接的对象,等等

任何简单的对象,可能需要一个或两个方法,并且只能通过嵌套一个或两个层次来构建,我也可以按字面意思构建(只要不需要初始化)

如果我需要其中的几个,也许我会制作一个构造函数。
但是,如果我只需要这样一种独特的东西,那么做这样的事情会不会让我省去一些麻烦呢:

var rectangle = (function (width, height) {
    var public_interface = {
        width  : width,
        height : height,
        area   : width * height,
        perimeter : (2 * width) + (2 * height)
    };
    return public_interface;
}(12, 24));
如果需要更高级的计算,我可以保留任何额外的变量,并从内部处理它们。
如果我需要在对象中包含敏感数据,以及处理这些数据的函数,那么我可以使用公共函数调用这些私有函数并返回结果,而不是提供访问

此外,如果我重构代码,并决定在某个时候重命名
rectangle
,那么任何嵌套3个或更多深度的函数(它们引用
rectangle
)也必须修改。
同样,如果你正在构造你的方法,这样他们就不需要直接要求任何比
this
更高的对象,那么你就不会有这个问题了

…但如果您有一个如下界面:

MyApp.myServices.webService.send();
它希望发现:

MyApp.appData.user.tokens.latest;  // where personally, I might leave tokens in a closure

如果您更改appData模块的结构,您的webService模块中会出现各种错误,直到您找到所有对旧格式的引用,并将它们全部重命名。

关于
this.doms.loginButton.on('click',this.events.onLoginButtonClicked')的情况如何?那可能有用,真不敢相信我没试过。但与模块化模式相比,编写还需要相当长的时间。因此,在任何情况下,除了隐私和个人偏好之外,使用对象文字与显示模块之间没有真正的优点/缺点?@henson和内部引用,在对象文字中,指向依赖其他属性的属性,这必须在事实发生后计算,或者在对象的方法中创建闭包,这要求属性在您尝试创建函数时预先存在。。。这一切都归结为复杂性。如果您可以管理所有对象构造,使所有大型对象都只是原始数据,那么对象文字就可以了。如果需要闭包,或者需要基于对象的预先存在的成员进行预计算,那么文本就是一堆
{}.init()
var rectangle = (function (width, height) {
    var public_interface = {
        width  : width,
        height : height,
        area   : width * height,
        perimeter : (2 * width) + (2 * height)
    };
    return public_interface;
}(12, 24));
MyApp.myServices.webService.send();
MyApp.appData.user.tokens.latest;  // where personally, I might leave tokens in a closure