статические шаблоны методов для функций конструктора в JavaScript - PullRequest
7 голосов
/ 29 января 2012
function Foo(){...}
Foo.bar = function (){...};

Это единственный шаблон для добавления статического метода в функцию конструктора?В частности, нельзя ли создать статический метод bar () в определении самого Foo ()?

Ответы [ 3 ]

9 голосов
/ 29 января 2012

Когда вы говорите «изнутри», звучит так, будто вам нужен чистый способ хранить все в одном месте. Вы могли бы потенциально использовать библиотеку наследования классов, которая поддерживает статические объявления. Или просто возьмите один и расширьте его самостоятельно, чтобы добавить эту возможность.

Для простого (но не очень компактного) способа сохранить все вместе, вы можете использовать что-то вроде этого:

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

Я обнаружил, что вышесказанное очень удобно, особенно когда вы используете шаблон фабричного дизайна. Ваш класс может иметь несколько статических фабричных методов в своем прототипе, и вы можете вызывать эти фабричные методы, даже если у вас есть только экземпляр, исходный класс которого вы не знаете.

0 голосов
/ 07 декабря 2017
 ( function (fn) {
     fn.bar = function (...) { ... } ;
     ...
 } ) ( Foo.prototype ) ;

Другими словами, вы создаете анонимную функцию, которая будет заполнять прототип Foo.

0 голосов
/ 29 января 2012

Вы можете создать статический метод в функции конструктора, но только с использованием того же синтаксиса:

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");
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...