我偶然发现了这篇文章:JavaScript 的揭示模式。我想在我的项目中使用它。
假设我有一个名为 abc
的函数,并且我在我的主 JavaScript 文件中调用该函数。
这种模式会使事情变得不同吗?有人可以展示一下这种模式的基本示例吗?
我偶然发现了这篇文章:JavaScript 的揭示模式。我想在我的项目中使用它。
假设我有一个名为 abc
的函数,并且我在我的主 JavaScript 文件中调用该函数。
这种模式会使事情变得不同吗?有人可以展示一下这种模式的基本示例吗?
一个小例子:
var revealed = function(){
var a = [1,2,3];
function abc(){
return (a[0]*a[1])+a[2];
}
return {
name: 'revealed',
abcfn: abc
}
}();
在初始化匿名函数中,用来给 revealed
赋值的 a
和 abc
是该函数私有的。该函数返回一个包含 name
属性和 abcfn
属性(一个指向 abc function
的引用)的对象字面量。abc function
使用了私有变量 a
。这都得益于使用了闭包(同一函数作用域内的所有内容都可以互相引用)。
使用 Revealed:
alert(revealed.name); //=> 'revealed'
alert(revealed.abcfn()); //=> 5 (1*2+3)
a
和abc
被封闭在内。 - KooiIncDC = Douglas Crockford
RMP = 模块模式
文章中已经列出了例子。您具体想问什么?因为这些与文件无关,而与闭包相关。
将所有内容放入一个闭包(函数)中,仅公开您希望被访问的部分。 DC风格和RMP之间的区别在于,在前者中,函数在不同位置定义,而在RMP中,它们始终在相同位置定义,然后在公共对象字面上显示。
因此,在DC和RMP中,您都有:
这两种模式仅在可读性方面存在差异。在DC情况下,您不总是知道某个功能将在何处定义,但在RMP中,您总是知道一切都在私有部分中。
var MyFunction = function(){
var _ = {
Init: function(){
_.Config.foo = "hello world";
},
Config:{
foo:null
},
ShowAlert:function(){
alert(_.Config.foo);
}
}
return {
Init: _.Init,
ShowAlert: _.ShowAlert
};
}();
MyFunction.Init();
MyFunction.ShowAlert();
我在我的博客上写了更多关于这个的信息:
http://curtistimson.co.uk/js/mixing-revealing-module-and-singleton-javascript-patterns/
补充一下:使用这种模式时,最好将全局依赖项作为参数传递,以使它们明确。你不必这样做,但这使得你的模块需要什么一眼就能看出来。例如:
var myModule = (function ($, loadModule) {
"use strict";
})(jQuery, load);
这里是揭示模块模式的小例子。
它提供了一个类似于类的声明私有和公共函数的功能。这是这种模式的主要优点。如果我们不想将某些功能从全局范围内公开访问,则将其设置为私有,其余部分则设置为公共。以下是如何创建私有和公共函数的示例。还有一件事,它是一个自执行的代码块。
var Calculator = (function () {
var num1 = 10;
var num2=5
var _abc = function () {
return num1 - num2;
};
var _mulFunc = function () {
return num1 * num2;
};
var _divFunc = function () {
return num1/num2;
};
return {
//public scope
abc: _abc,
mulFunc:_mulFunc
};
})();
警告(Calculator.abc()); 返回5
警告(Calculator.mulFunc()); 返回50
而__divFunc()将无法访问,因为它在私有范围内。 我们只能访问那些在返回对象中声明的函数, 因为它是公共函数的表示
揭示模块的基本概念是,您有一个对象
,它封装其数据和行为:
var Module = (function(){
var privateStuff = {};
var publicStuff = {};
return publicStuff;
})();
然而,在使用这种模式时,有一些最佳实践应该采用。以下是一个模块(“Modulus
”),它具有一些属性,仅供演示目的,并采用了其中一些实践:
function AbstractSomeClass(id) {
this.id = id;
return this;
}
var Modulus = (new (function SomeClass() {
var thus = this;
function NameClass(name){
this.value = thus.name || name;
}
AbstractSomeClass.call(this, 998);
this.name = 'Touring';
this.name = ( new NameClass('Hofstadter') ).value;
return {
id: this.id,
name: this.name
};
})());
(new (function SomeClass(){ ... })());
语法。像这样使用 new
允许你在闭包内部使用 this
关键字。如果你需要从另一个类继承属性 (AbstractSomeClass.call(this, 998);
),这非常方便 -- 然而,你仍然需要 公开 你想要公开的属性,例如:
return {
id: this.id,
name: this.name
};
this
分配给thus
——这使我们能够在具有自己的this
作用域的子类中使用父级this
(this.value = thus.name || name;
)对于模块外部的代码来说,这并没有什么区别。在那篇文章中的所有3种情况下,方法的调用方式都是相同的。但是模块本身的结构在内部是不同的。
Crockford的模块模式和他们所谓的“揭示模块模式”在结构上基本上是相同的。唯一的区别是它们首先将方法分配给一个本地变量,以便更易读。但实际上并没有什么特别之处,你在链接中就有一些例子。
https://tarunnagpal78.medium.com/revealing-module-design-pattern-in-javascript-3b0db0bcd121
我已经写了一篇关于它的文章。
你可以看一下这个。