如何在JavaScript中使用Chain Pattern和Self Revealing Module Pattern?

9

我有以下代码:

filtersManager = (function ($) {

    var that = this;

    function configure() {

        // some work

        return that;
    };

    function process() {

       // some work

        return that;
    }    

    return {
        // public functions
        configure: configure,
        process: process
    };
}(jQuery));

但是当使用以下代码调用时,它会失败:
filtersManager.configure().process();

Error: Object doesn't support property or method 'process'

下面的代码有效:
filtersManager.configure();
filtersManager.process();

1
IIFE没有上下文,this取决于你如何调用函数。每个函数内部的this已经是对象。 - elclanrs
我尝试使用“this”并且它有效,但我想避免直接使用“this”。万一该方法也从类中的另一个私有函数调用,该函数会更改上下文。 - The Light
}(jQuery)); 这是正确的闭合方式,不应该是 })(jQuery); - Jai
@Jai 是的,但前者更受欢迎。 - Royi Namir
1
@Jai:这是有效的,只是语义问题。实际上}(jQuery))更有意义,因为函数被调用并用括号包裹以强制表达式。 - elclanrs
虽然有点晚了,但是结果被分配给filtersManager时,它被强制为一个表达式,函数不需要额外的括号 :-) :filtersManager = function ($) { ... }(jQuery); - imma
4个回答

15

你返回了错误的值(在普通函数调用中,this是全局对象)。你想要返回最初创建的对象,我将其称为接口

filtersManager = (function ($) {

    var interface = {
        // public functions
        configure: configure,
        process: process
    };

    function configure() {

        // some work

        return interface;
    };

    function process() {

       // some work

        return interface;
    }    

    return interface;
}(jQuery));
如果你想知道为什么我可以引用下面定义的函数,那是因为提升机制。

仍然是我最喜欢和最灵活的js模式之一。 - evolutionxbox

2

立即执行函数在全局对象(window)上下文中执行。尝试类似于这样的代码:

filtersManager = (function ($) {

    var that = {};

    that.configure = function() {
        // some work
        return that;
    };

    that.process = function() {
        // some work
        return that;
    }

    return that;

}(jQuery));

更新:根据评论

构造函数模式似乎更适合您的需求:

var FiltersManager = (function($) {

    function FiltersManager() {}

    FiltersManager.prototype = {
        configure: function() {
            console.log('configure');
            return this;
        },
        process: function() {
            console.log('process');
            return this;
        }
    }

    return FiltersManager;

}(jQuery));

new FiltersManager().configure().process();

嗯,{} 不是一个空对象。它不一定反映相同的对象。 - The Light
@TheLight 你是什么意思? - dfsq
我的意思是P{创建一个新的空对象,而我想引用相同的filtersManager对象。 - The Light

0
关于继续别人的讨论,我认为你可能混淆了函数构造器语法,这将起作用,与你所说的类似。
var G=function g()
{
  this.configure =function (){return this;}
  this.process  =function (){return this;}
};

var _= new G();




console.log(_.configure().process())

那样做是可行的,但我认为将这些方法放在原型上会更好。 - alex
@alex 同意。只是想指出还有其他方法,看起来与他的基本语法相似。 - Royi Namir

0
如果你想要在其他对象上重复使用这些函数,可以这样做。

filtersManager = function ($) {

    function configure() {

        // some work

        return this;
    };

    function process() {

       // some work

        return this;
    }    

    return {
        // public functions
        configure: configure,
        process: process
    };
}(jQuery);

另一方面,如果您想要为它们创建别名,则需要将它们绑定到对象

或者如果configure和process是相当简短、简单的函数:

filtersManager = (function ($) {

    return {
      
        // public functions
        configure: function () {

            // some work

            return this;
        },
      
        process: function () {

           // some work

            return this;
        }
    };
}(jQuery));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接