Функция возврата iife работает некорректно

Я пытаюсь создать модуль, и я пытаюсь использовать правильный дизайн. Я видел эту библиотеку, и у них была функция iife, возвращающая function это модуль. Я пытался сделать это так:

(function() {
  function MyModule() {
    var something = 'something';
    this.log = log();
  }

  MyModule.prototype.alert = function() {
    alert(this.something);
  };

  function log() {
    console.log('hello');
  }

  return MyModule;
})();

var module1 = new MyModule();

Но я получаю следующую ошибку:

Uncaught ReferenceError: MyModule не определен

Вот соответствующий скопированный код:

Что я делаю неправильно, и как я могу это исправить?


person Jessica    schedule 17.07.2016    source источник
comment
Вам нужно назначить то, что IIFE возвращает переменной MyModule   -  person zerkms    schedule 18.07.2016
comment
а зачем вам определять его в iife, если вы хотите получить глобальный доступ к этой функции? Это то, что они предназначены для предотвращения лол..   -  person Gogol    schedule 18.07.2016
comment
@SugatoSengupta сделать функцию log приватной? (правда здесь это не приносит никакой пользы).   -  person zerkms    schedule 18.07.2016
comment
да ладно, я понял .. Как насчет использования классов? Надеюсь, это не синглтон.   -  person Gogol    schedule 18.07.2016
comment
@SugatoSengupta Классы не помогут: в JS нет способа сделать что-то недоступное, кроме как с помощью модулей IIFE/ES2015.   -  person zerkms    schedule 18.07.2016
comment
не знаю, может быть.. Я думаю, что это все равно не нужно.. Пользователи все равно могут видеть реализацию журнала. Сделать его приватным не поможет.   -  person Gogol    schedule 18.07.2016
comment
@SugatoSengupta, ну, дело не в том, чтобы сделать его невидимым, поскольку вы не можете. Речь идет о том, чтобы сделать вещи приватными.   -  person zerkms    schedule 18.07.2016
comment
ну, конечно.. В любом случае, это код на стороне клиента.. Я еще не пробовал приватные вещи private способом. Не знаю, зачем мне это нужно, но это вне контекста :)   -  person Gogol    schedule 18.07.2016
comment
@SugatoSengupta var counter = (() => { let cnt = 0; return () => ++cnt; })(); вот пример. Это функция счетчика с локальным значением счетчика, с которым вы не можете связываться, даже если хотите.   -  person zerkms    schedule 18.07.2016
comment
что это? ЭС6? Извините, я не могу распознать его, я слишком медленный, лол   -  person Gogol    schedule 18.07.2016
comment
@SugatoSengupta Это ecmascript 6. Это не так сложно понять, если вы знаете ecmascript 5. Просто посмотрите ссылки   -  person Jessica    schedule 18.07.2016


Ответы (2)


MyModule остается внутри закрытия IIFE, поэтому он не будет виден из кода снаружи. Назначьте результат IIFE переменной MyModule

Кроме того, вы, вероятно, имели в виду присвоить функцию log строящемуся MyModule, а не его результату (undefined)

И, наконец, тот факт, что вы объявляете переменную с именем something в конструкторе, не назначает ее как свойство создаваемого объекта. Если вы хотите, чтобы something был приватным, вы должны объявить метод alert внутри закрытия конструктора:

var MyModule = (function() {
  function MyModule() {
    var something = 'something';
    this.log = log;
    // this.log = log();

    this.alert = function() {
        alert(something);
    };
  }

  //MyModule.prototype.alert = function() {
  //    alert(this.something);
  //};

  function log() {
    console.log('hello');
  }

  return MyModule;
})();

var module1 = new MyModule();

module1.alert(); // Alerts 'something'
module1.log(); // Logs 'hello'

Чтобы по-настоящему понять JavaScript, забудьте о классах, изучите прототипы и функции в целом, особенно clousures.

Посмотрите эту блестящую конференцию Дугласа Крокфорда, чтобы понять, как все правильно.

person Marco Scabbiolo    schedule 17.07.2016
comment
Спасибо! Я подумал, что это может быть проблемой, но когда я проверил библиотеку, опубликованную в вопросе, они не сделали var MyModule = (function() {, они просто сделали return без задания. - person Jessica; 18.07.2016
comment
В этой библиотеке они назначают переменную как глобальную переменную, назначая ее объекту окна: window["Sortable"] = factory();, контрольная строка 22. Это то же самое, что и Sortable = .... - person Marco Scabbiolo; 18.07.2016
comment
ой. На самом деле я не знал, что делают 3 оператора if. Я собирался проверить, что он делает, когда закончу свой проект. Лучше использовать Sortable = ... или сделать переменную глобальной? Не безопаснее ли не делать это глобальным? Но я вижу, что в большинстве библиотек есть 3 оператора if, поэтому я не уверен, что лучше. - person Jessica; 18.07.2016
comment
Безопаснее не делать его глобальным, но это зависит от среды. Эти библиотеки готовы работать как модули, если среда поддерживает это, но в случае браузера они должны полагаться на глобальные переменные. - person Marco Scabbiolo; 18.07.2016

Я не совсем уверен, что вы пытаетесь сделать с этим модулем, но судя по тому, как он выглядит. Это всегда будет регистрировать приветствие и настраивает функцию оповещения, которая предупреждает «что-то».

var MyModule = (function() {
    var something = 'something';

  this.prototype.alert = function() {
    alert(this.something);
  };

    console.log('hello');
})();

var module1 = new MyModule();

Однако, если вы хотите настроить это так, чтобы передавать различные вещи для оповещения и регистрации, вы сможете сделать это таким образом.

var MyModule = (function( txt ) {
    var something = this.txt;

  this.prototype.alert = function() {
    alert(something);
  };

    console.log('hello '+ something);
})();

var module1 = new MyModule();
   module1('this is awesome text');
person andre mcgruder    schedule 17.07.2016