Singleton中的公共函数调用自身

时间:2013-11-25 11:31:58

标签: javascript singleton

我正在尝试使用单例模式但是我在实现递归公共函数时遇到了麻烦。

var singleton = (function(){
    var self = this;
    function privateFunc(){
        console.log('I can only be accessed from within!');
    }
    return{
        publicFunc: function(){
            //More stuff here
            setTimeout(self.publicFunc, 1000);
        }
    }
})();

我用singleton.publicFunc

来调用它

我收到此错误Uncaught TypeError: Cannot call method 'publicFunc' of undefined

我的理解是var self实际上是这个实例中的Window对象,所以我必须传递singleton.publicFunc作为回调才能工作,但它似乎不是很“干”(Don)不要重复自己)。在那儿 使用单身人士时更好的方法来实现这一目标吗?

使用API​​调用

var wikiAPI = (function(){
    var self = this;
    return {
      getRandomArticle : function() {
        return $.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exintro=&format=json&callback=?", function (data) {
        });
      },
      fireAPICalls : function() {
        self.getRandomArticle().done(function(data) {
          for(var id in data.query.pages) {
            this.data = data.query.pages[id];
          }
          console.log(this.data);
          setTimeout(self.fireAPICalls, 1000);
        });
      }
    }
  })();

3 个答案:

答案 0 :(得分:2)

您可以像named function expression那样使用:

var singleton = (function(){
    var self = this;
    function privateFunc(){
        console.log('I can only be accessed from within!');
    }
    return{
        publicFunc: function nameVisibleOnlyInsideThisFunction(){
                           //^-------------------------------^
            //More stuff here
            setTimeout(nameVisibleOnlyInsideThisFunction, 1000);
        }
    }
})();

我刚看到你的编辑。有什么办法可以参考你试图调用的函数。那么这样的事情怎么样:

var wikiAPI = (function(){
    var self = this;
    var randomArticle = function() {
        return $.getJSON("http://en.wikipedia.org/w/api.php?action=query&generator=random&grnnamespace=0&prop=extracts&exintro=&format=json&callback=?", function (data) {
        });
      };
    var repeatFunc = function fireApi() {
        randomArticle().done(function(data) {
          for(var id in data.query.pages) {
            this.data = data.query.pages[id];
          }
          console.log(this.data);
          setTimeout(fireApi, 1000);
        });
      };
    return {
      getRandomArticle : randomArticle,
      fireAPICalls : repeatFunc
    }
  })();

答案 1 :(得分:2)

使用setTimeout()中的bind将函数绑定到正确的范围:

publicFunc: function() {
    setTimeout(this.publicFunc.bind(this), 1000);
}

演示:http://jsfiddle.net/te3Ru/

答案 2 :(得分:0)

您无法在IIFE中使用this。如果你想正确使用this,你需要创建一个函数的对象/实例,如下所示:

var singleton = (function () {
    // allow to omit "new" when declaring an object
    if (!(this instanceof singleton)) return new singleton();

    var self = this,                      // self now points to "this"
        privateFunc = function () {
            console.log('I can only be accessed from within!');
        };

    this.publicFunc = function() {
        console.log(this);                // this now points to the correct object
        setTimeout(function () {
            self.publicFunc.call(self);   // call function in the "self" scope
        }, 1000);
    };
    return this;
});

singleton().publicFunc();

现在它不是一个单身人士,但你可以与javascript最接近privatepublic