javascript中构造函数的静态方法模式

时间:2012-01-29 19:01:34

标签: javascript methods static design-patterns

function Foo(){...}
Foo.bar = function (){...};

这是将静态方法添加到构造函数的唯一模式吗?特别是,是否无法在Foo()本身的定义中创建静态方法bar()?

3 个答案:

答案 0 :(得分:9)

当你说“内部”时,听起来你需要一种干净的方式将所有东西放在一个地方。您可以使用支持静态声明的类继承库。或者只需拿一个并自己扩展即可添加该功能。

对于一个简单(但不那么紧凑)的方法来保持所有内容,你可以使用这样的东西:

var Foo = (function () {
    var ctor = function () {
        // the constructor
    };

    ctor.staticMethod = function () {
        // something static
    };

    return ctor;
})();

但是!真正重要的是使声明不言自明,它是静态的吗?您可以简单地将静态方法声明为原型方法,并通过一些代码注释传达它们是静态的(即不作用于实例)方法。没有任何合同执行如何调用这些方法,但几乎没有副作用。所以我会选择:

function Foo() {
    // the constructor
    // optionally define instance methods here
}

Foo.prototype = {
    instanceMethod: function () {
        // some instance method
        // this.bar(); ...
    },
    staticMethod: function () {
        // some static method
        // return 2 + 3;
    }
};

用法:

// Using "prototype" explicitly can be your contract for saying "this is static"
var sum = Foo.prototype.staticMethod();

var inst = new Foo();

var sum2 = inst.staticMethod(); // You have the added benefit of being able to call your static methods on instances

我发现上述内容非常方便,特别是当您使用工厂设计模式时。您的类在其原型中可以有一些静态工厂方法,即使您只有一个您不知道其原始类的实例,也可以调用这些工厂方法。

答案 1 :(得分:0)

可以在构造函数中创建一个静态方法,但只能使用相同的语法:

function Foo(){
    Foo.bar = function (){...};
}

但是这只会在调用构造函数后添加静态方法。此外,它会在调用构造函数的每个额外时间重新添加它,这看起来很浪费,但我想这可能是有用的,例如:

function Foo() {
    var counter = (Foo.bar && Foo.bar() || 0) + 1;
    Foo.bar = function (){
        return counter;
    };
}

f = new Foo();
Foo.bar(); // 1
f2 = new Foo();
Foo.bar(); // 2

在这种情况下,更新bar以返回Foo被调用的次数 - 这里可能存在一个合理的变体,可以以有用的方式跟踪所有实例。

如果你真的不想因某种原因引用Foo,你可能会很聪明并做这样的事情:

var Foo = (function Private(){
    Private.bar = function (){...};
});

同样,这仅在Foo被调用至少一次后才有效。此外,虽然这确实展示了另一种语法,但我很难想象你什么时候想要使用它。

这里的另一种变化,可能同样无用:

function Foo() {
    this.constructor.bar = function (){
        console.log("test");
    };
}

答案 2 :(得分:0)

 ( function (fn) {
     fn.bar = function (...) { ... } ;
     ...
 } ) ( Foo.prototype ) ;

换句话说,你创建了一个匿名函数,它将填充Foo的原型。