Частный метод в шаблоне модуля: TypeError: undefined не является функцией

Я пытаюсь реализовать классический шаблон модуля в javascript, обсуждаемый здесь и здесь. Но мои частные методы не работают. У меня есть следующий бит тестового кода.

var jsStuff = (function() {

    // Private
    var sayStuffPrivate = function ( stuff ) {
        console.log( "I am a private method: " +  stuff );
        return true;
    };

    // Public
    return {
        sayStuff: function ( stuff ) {
            console.log( "I am a public method: " + stuff );
            this.sayStuffPrivate( stuff );
            return true;
        }
    }
}());

Когда я пытаюсь запустить это, я получаю следующее:

> jsStuff.sayStuff('blah');
test.js:16 I am a public method: blah
test.js:17 Uncaught TypeError: undefined is not a function

Что мне здесь не хватает?


person Dave    schedule 11.12.2014    source источник
comment
Это не метод, так как это означало бы, что он больше не является частным. Это просто локальная функция, и к ней следует обращаться как таковой; не через this. как публичное свойство вашего объекта.   -  person Bergi    schedule 11.12.2014
comment
Обратите внимание, что значение this внутри функции полностью определяется тем, как вы вызываете функцию (или с помощью bind), а не лексически (или как функция была создана).   -  person RobG    schedule 11.12.2014


Ответы (2)


this.sayStuffPrivate( stuff );

Здесь this относится к объекту, который вы фактически вернули из функции sayStuff. В нем нет свойства с именем sayStuffPrivate. Таким образом, this.sayStuffPrivate будет оцениваться как undefined, и, поскольку вы используете это как функцию, происходит сбой с этой ошибкой.

Вы должны воспользоваться свойством закрытия и вызвать его следующим образом.

sayStuffPrivate( stuff );
person thefourtheye    schedule 11.12.2014
comment
Спасибо! Я новичок в js, и это кажется такой тонкой вещью. Очевидно, я думаю, если вы видели это несколько раз. - person Dave; 11.12.2014
comment
Кстати, могут ли приватные методы вызывать публичные? Если да, то как? - person Dave; 11.12.2014
comment
Это ответило на мой второй вопрос (могут ли частные методы вызывать общедоступные?): stackoverflow.com/questions/4505073/ - person Dave; 11.12.2014

Вы должны вызывать sayStuffPrivate без этого. Попробуй это:

var jsStuff = (function() {

    // Private
    var sayStuffPrivate = function ( stuff ) {
        console.log( "I am a private method: " +  stuff );
        return true;
    };

    // Public
    return {
        sayStuff: function ( stuff ) {
            console.log( "I am a public method: " + stuff );
            sayStuffPrivate( stuff );
            return true;
        }
    }
}());
person Ali Movahedi    schedule 11.12.2014