gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:21:05 28 4
gpt4 key购买 nike

这可能已经被问过很多次了,我已经搜索过 SO 但到目前为止,我读到的所有答案都不是我正在寻找的。

我在一个网站上工作,该网站具有适度的 DOM 元素显示/隐藏、一些 AJAX 调用,可能还有其他内容。所以我将有两个主要脚本文件(HTML5 样板标准)

plugins.js // third party plugins here
site.js // all my site specific code here

之前我使用的是对象字面量设计模式,所以我的 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 Dev Tools 测试它们)。但是,我打算将网站的一些功能分离为更模块化的样式,因此我希望在上面的代码下方(或在单独的文件中)有这样的东西:

site.auth = {
init: function() {
site.auth.doms.loginButton.on('click', site.auth.events.onLoginButtonClicked);
},
doms: {
loginButton: $('.login'),
registerButton: $('.register')
},
events: {
onLoginButtonClicked: function() {
}
},
fbLogin: function() {
}
};

site.dashboard = {
};

site.quiz = {
};

// more modules

如您所见,它的可读性很强。但是有一个明显的缺点,那就是我必须编写类似 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% 公开的,那么只需使用一个文字(或多个文字),如果需要,使用嵌套对象,就完全没问题,假设你可以防止它变成一个巨大的代码球。

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

也就是说:
您根本不需要使用 .init 方法来揭示模块。
如果您的模块可以自包含,那么只需专注于导出您想要公开的内容。

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

这样做的好处是微乎其微的,只是增加了对任何需要公开的东西都需要附加到界面的理解。

您目前使用它的方式:

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

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

不比字面量好或坏,因为你可以很容易地做到这一点:

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

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

在您找到不适合您的东西之前,请使用满足您需求的东西。

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

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

// ex:
var rectangle = {
width : 12,
height : 24,
area : 0,
perimeter : 0,
init_area : function () { this.area = this.width * this.height; return this; }, // buh...
init_perimeter : function () { this.perimeter = (this.width * 2) + (this.height * 2); return this; } // double-buh...
}.init_area().init_perimeter();

如果我需要其中的几个,也许我会制作一个构造函数。
但是,如果我只需要像这样独特的东西之一,那么做这样的事情难道不会让我头疼吗:

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));

如果需要更高级的计算,我可以将任何额外的变量保密,并从内部处理它们。
如果我需要在对象内部拥有敏感数据,并需要函数来处理该数据,那么我可以拥有调用这些私有(private)函数并返回结果的公共(public)函数,而不是提供访问权限。

另外,如果我重构我的代码,并决定在某个时候重命名 rectangle,那么任何嵌套 3 层或更深的函数,它们指的是 rectangle 将有也要修改。
同样,如果你正在构建你的方法,这样它们就不需要直接请求任何比 this 更上层的对象,那么你就不会有这个问题......

...但是如果您的界面如下所示:

MyApp.myServices.webService.send();

它期望找到:

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

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

关于javascript - 对象文字或模块化 Javascript 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15718757/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com