gpt4 book ai didi

JavaScript 模块模式差异

转载 作者:行者123 更新时间:2023-11-29 21:32:25 24 4
gpt4 key购买 nike

我正在努力思考不同的模块模式偏 Angular 。我看到了编写这些模块和公开其数据的不同方式。

我期待有关优势/劣势、此处未描述的更好模式的信息,以及它们各自的用例。


A) 包含在自调用函数中的对象文字,使用 init 方法触发: (source)

(function() {

var MyModule = {
settings: {
someProperty: 'value';
}

init: function() {
someMethod();
}

someMethod: function() {
// ...
}
};

MyModule.init();
})();

This是我构建的简单“Tweet This”实用程序的示例。我是否正确使用了这种模式?到目前为止,这是我唯一有实际写作经验的。


B) 作为命名空间自调用匿名函数的模块: (source)

var MyModule = (function () {
var MyObj = {}

function privateMethod() {
// ...
}

MyObj.someProperty = 1;
MyObj.moduleMethod = function () {
// ...
};

return MyObj;
}());

与以前的风格相比有什么优势/劣势吗?另外,在这里使用对象文字表示法而不是示例中的点语法会有什么影响?对象字面量看起来更简洁、更容易,但我真的不知道每个对象的正确用例?


C) 模块作为命名空间自调用匿名函数,但仅通过return block 公开所需结果: (source)

var MyModule = (function() {
var myPrivateVar, myPrivateMethod;

myPrivateVar = 0;

myPrivateMethod = function(foo) {
console.log(foo);
};

return {
myPublicVar: "foo",

myPublicFunction: function(bar) {
myPrivateVar++;
myPrivateMethod(bar);
}
};

})();

与之前的样式类似,但我们不是公开整个对象及其所有属性/方法,而是通过 return 语句公开特定的数据位。


D) 模块作为封装在自调用匿名函数中的函数,嵌套函数充当方法。该模块通过 window 对象公开,然后通过 new 关键字构造:(source)

(function(window, undefined) {

function MyModule() {

this.myMethod = function myMethod() {
// ...
};

this.myOtherMethod = function myOtherMethod() {
// ...
};

}

window.MyModule = MyModule;

})(window);

var myModule = new MyModule();
myModule.myMethod();
myModule.myOtherMethod();

我假设这种模式的优势在于,如果模块是某种"template",应用程序中可能需要存在多个实体。有什么好的用例的具体例子吗?

最佳答案

所有这些都使用相同的模式,只是方式略有不同。

A) 包装在自调用函数中的对象文字,使用 init 方法触发:

如果您不想让任何其他人访问一段代码,这很好。您甚至不必拥有 init 函数。将代码包装在 IIFE(立即调用的函数表达式)中可防止全局命名空间污染并允许使用“私有(private)”变量。在我看来,这只是一个很好的实践,而不是一个模块。

B) 作为命名空间自调用匿名函数的模块:

这就是人们谈论模块模式时的意思。它为您提供私有(private)变量和函数,然后通过公共(public)接口(interface)公开这些变量和函数。在您的示例中,该接口(interface)恰好被称为 MyObj

C) 模块作为命名空间自调用匿名函数,但仅通过 return block 公开所需结果:

这实际上与 B 完全相同。唯一的区别是接口(interface)上的方法不能像在 B 中那样直接引用接口(interface)本身。示例:

MyObj.methodA = function() {
return MyObj.methodB();
};

这将适用于前面的示例,因为您有一个名称来引用它,但仅当您希望使用除返回对象以外的任何对象作为执行上下文来调用公共(public)方法时才有用。即,setTimeout(MyModule.methodA)(将在全局上下文中调用,因此 this.methodB() 不会按预期工作。

D) 模块作为封装在自调用匿名函数中的函数,嵌套函数充当方法。该模块通过 window 对象公开,然后通过 new 关键字构建:

除 2 个细微差别外,与前 2 个相同。 window 被作为参数传递,因为历史上确实是访问局部变量比访问全局变量更快,因为引擎不必向上爬作用域链。然而,如今大多数 JS 引擎都优化了对 window 的访问,因为它是常见的已知对象。同样,undefined 作为参数给出,没有任何参数作为参数传递。这确保您有一个正确的 undefined 值。这背后的原因是,从技术上讲,您可以在非严格模式下为 undefined 分配任何值。这意味着某些第 3 方可以编写 undefined = true; 并且突然之间所有的 undefined 检查都失败了。

另一个区别是你返回的是一个函数而不是一个对象。这背后的好处是您可以拥有在对象的每个实例中共享的私有(private)变量,以及每个实例的私有(private)变量。示例:

var count = 0;
function MyObject(id) {
var myID = id;
count++;

// Private ID
this.getID = function() {
return myID;
};

// Number of instances that have been created
this.getCount = function() {
return count;
};
}

这样做的缺点是您没有将方法附加到原型(prototype)。这意味着 JS 引擎必须为对象的每个实例创建一个全新的函数。如果它在原型(prototype)上,所有实例将共享相同的函数,但不能有单独的私有(private)变量。

关于JavaScript 模块模式差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35851908/

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