Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.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_Oop_Design Patterns - Fatal编程技术网

如何在JavaScript中正确使用模块模式?

如何在JavaScript中正确使用模块模式?,javascript,oop,design-patterns,Javascript,Oop,Design Patterns,在我的公司里,我们有一个调查框架来帮助利益相关者创建调查,我正在尝试创建一个可重用的对象,它允许团队成员轻松地为调查设置一个特定问题的宽度——根据答案的长度,有时会有点压扁。我尝试使用模块和构造函数模式的组合,但不确定是否正确地实现了它。有没有更好的方法来编写我的代码 var WidthIncreaser = (function(){ return function (element, words, width) { va

在我的公司里,我们有一个调查框架来帮助利益相关者创建调查,我正在尝试创建一个可重用的对象,它允许团队成员轻松地为调查设置一个特定问题的宽度——根据答案的长度,有时会有点压扁。我尝试使用模块和构造函数模式的组合,但不确定是否正确地实现了它。有没有更好的方法来编写我的代码

        var WidthIncreaser = (function(){
            return function (element, words, width) {

                var element = $(element);
                var re = new RegExp(words, 'gi');

                return {
                    init: function() {
                        if (element.text().match(re)) {
                            element.width(width);
                        }
                    }
                };
            };
        })();

        var tr = new WidthIncreaser('td.choicev-question:first', 'Applicable from the', 400);
        tr.init();
这个想法是,有人可以创建一个WidthIncreaser的新实例,并传入一个元素,一个与问题文本匹配的字符串,这样它就是正确的问题目标和设置问题宽度的大小


提前谢谢你的建议

你是双重包装的东西。无论如何,我看到的常见模块模式只是一个返回带有闭包的对象的函数

不需要
新的
关键字,也不需要即时功能。当只生成一个对象并将其直接指定给一个变量时,通常使用即时函数。在您的案例中,您希望创建“实例”


我使用的模块模式通常如下所示:

var myModule = (function () {
    var myPrivateVar = 'foo';
    var myPrivateFunc = function () {
        console.log('bar');
    };

    return {
        myPublicFunc: function () {
            console.log(myPrivateVar);
        }
    };
}) ();
myModule.myPublicFunc();
然后它将被这样使用:

var myModule = (function () {
    var myPrivateVar = 'foo';
    var myPrivateFunc = function () {
        console.log('bar');
    };

    return {
        myPublicFunc: function () {
            console.log(myPrivateVar);
        }
    };
}) ();
myModule.myPublicFunc();

我不认为你真的需要“模块模式”。您只需利用闭包即可,仅此而已:

function WidthIncreaser(element, words, width) {
    element = $(element);
    var re = new RegExp(words, 'gi');

    this.init = function () {
        if (element.text().match(re)) {
            element.width(width);
        }
    }
}

var tr = new WidthIncreaser('td.choicev-question:first', 'Applicable from the', 400);

tr.init();
当然,在这种情况下,您不需要必要的
init
,因为您可以将所有内容都放在ctor中,但我假设这只是一个示例,可能您需要延迟初始化

通过这种方式,您可以保留
原型
链,您可以使用以下语句:

tr instanceof WidthIncreaser//true

威尔工作

此外,您还可以使用不需要访问作用域变量(至少不直接访问)的方法来填充
原型

WidthIncreaser.prototype.doSomething=函数(){/*..*/}

例如,如果由于交叉浏览限制而无法使用getter和setter,则可以使用如下函数:

function WidthIncreaser(element, words, width) {
    element = $(element);
    var re = new RegExp(words, 'gi');

    this.element = function() { return element };

    this.init = function () {
        if (element.text().match(re)) {
            element.width(width);
        }
    }
}

WidthIncreaser.prototype.reset = function () {
    this.element().text("")
}
因此基本上您可以从外部检索元素,但它是只读的,
WidthIncreaser
只能在实例化期间设置元素


Edit:我复制并粘贴了
init
,当然它对
re
的依赖项不起作用,所以这是一个很糟糕的例子来说明这种方法。

我不明白为什么要用这种方式保护
元素。最好只设置
this.element=$(element)
。更简单。所有的问题都是关于“保护”的,这就是为什么。当然,您总是可以覆盖公共方法以提供不同的内容,但是您没有对变量的直接访问权。我个人更喜欢使用现代浏览器,让您在ES5方面有更大的灵活性。否则就没有必要采取这种做法,公共财产也可以。