使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?
Posted
技术标签:
【中文标题】使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?【英文标题】:Using the module pattern with multiple modules, how can an event listener in one module use a callback from another module? 【发布时间】:2021-11-02 04:47:05 【问题描述】:例如
const Foo = (function ()
const something = [];
const method1 = function()
bar.addEventListener("click", method2); //how can I access this method from Foo2??
;
return method1;
)();
const Foo2 = (function ()
const method1 = Foo(???); //the example ive found that was remotely close
const somethingElse = 10;
const method2 = function()
//do something
;
return method2;
)();
在一个示例中,我发现他们使用了对象解构并将其设置为等于我想从中继承该特定函数的另一个模块。我试图实现这个,但它告诉我Foo
不是一个函数,或者我试图在没有初始化的情况下访问它。
在他们的示例中,他们在Foo
的括号中有一个变量,但是将其应用于我的项目 idk 括号中的内容,我尝试的所有内容都是错误的,甚至是空括号。此外,即使这确实有效,我也不知道在事件侦听器中的回调函数名称前面放什么。我试过bar.addEventListener("click", Foo2.method2);
和bar.addEventListener("click", Foo2.method2());
我看到这个问题以不同的方式提出了几个不同的答案,但老实说,这些解释只是超出了我的理解水平。对象解构对我来说最有意义,但它仍然不起作用,所以我不知道该怎么办。
我了解原型继承并且能够说Foo.prototype.someFunction
能够使用Foo
中的方法,但是实现此功能的“工厂函数/模块模式”等价物是什么?
不仅仅是事件,这两个模块如何相互连接?是语法错误,还是不可能?我只是想举个例子……某事。任务要求我们使用工厂函数和模块模式,我找不到任何资源,我可以找到简单的如何将常规函数转换为模块的资源,没有关于一旦你拥有多个模块后如何使用它们的资源不管什么原因。
【问题讨论】:
【参考方案1】:解释为什么这不起作用比解释你应该做什么更容易,因为老实说这是一种奇怪的方法。
Foo
中的函数会立即被调用。分配给Foo
的值不是函数——它是函数的返回值,它是一个具有method1
属性的对象。
在Foo2
内部,您可以使用const method1 = Foo;
访问变量Foo
的值。但是您不能在Foo
中访问Foo2
,因为该函数被立即 调用,这意味着您正在尝试在定义之前访问Foo2
。您不能简单地重新排序代码,因为您在 Foo
和 Foo2
之间存在循环依赖关系。
简而言之,使用 IIFE 无法做到这一点。
所以不要立即调用你的函数。 Foo
可以是一个工厂,它接受一些参数并返回一个带有method1
的对象,Foo2
也是如此
如果您这样做,那么您可以拥有多个不同的 foo 对象实例。例如,const a = Foo2(5); const b = Foo2(10);
。在不知道实际目标的情况下,我很难知道设计它的最佳方式。
如果您需要这种循环行为,其中 1 和 2 相互引用,那么这很难。您可能需要/希望您的 foo 工厂之一将另一个工厂的实例作为其参数之一。您可能需要/想要使用函数的 this
值。这将是一团糟。
如果是单向关系,那就容易多了。
这里我们创建一个Foo2
实例并将其传递给Foo
:
const bar = document.getElementById('bar');
// takes a Foo2 instance as an argument
const Foo = function (foo2Instance)
const something = [];
const method1 = function()
bar.addEventListener("click", foo2Instance.method2);
;
return method1;
// takes a number as an argument
const Foo2 = function (somethingElse)
const method2 = function()
alert(somethingElse);
;
return method2;
const myFoo2 = Foo2(10);
const myFoo = Foo(myFoo2);
myFoo.method1();
<body>
<div id="bar">Click Me</div>
</body>
这里Foo
负责创建自己的内部Foo2
实例。计数器“A”和“B”是完全分开的,单击一个不会增加另一个。这是因为每个 Foo
实例都有自己的 Foo2
实例。
const Foo = function (counterId)
const bar = document.getElementById(counterId);
const foo2Instance = Foo2();
const method1 = function()
bar.addEventListener("click", foo2Instance.method2);
;
return method1;
const Foo2 = function ()
let count = 0
const method2 = function()
count++;
console.log(`count is $count`);
;
return method2;
const counterA = Foo("a");
counterA.method1();
const counterB = Foo("b");
counterB.method1();
<body>
<div id="a">Counter A</div>
<div id="b">Counter B</div>
</body>
【讨论】:
以上是关于使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?的主要内容,如果未能解决你的问题,请参考以下文章