Как правильно настроить этот «публичный» метод? - PullRequest
5 голосов
/ 13 декабря 2011

У меня есть этот код (JSFiddle)

var OBJ = function(){
    var privateVar = 23;
    var self = this;

    return {
        thePrivateVar : function() {
          return privateVar;
        },  

        thePrivateVarTimeout : function() {
            setTimeout(function() { alert(self.thePrivateVar()); } , 10);
        }
    }

}();

alert(OBJ.thePrivateVar());

OBJ.thePrivateVarTimeout();

Это абстракция реальной проблемы, с которой я столкнулся.

Итак - я ожидаю, что вызов OBJ.thePrivateVarTimeout() будет ждать 10, а затем alert с 23 (к которому я хочу получить доступ через другой открытый метод).

Однако self, похоже, настроен неправильно. Когда я устанавливаю self = this, кажется, что this не ссылка на функцию, а ссылка на глобальный объект. Почему это?

Как я могу сделать публичный метод thePrivateVarTimeout вызывать другой публичный метод thePrivateVar?

1 Ответ

5 голосов
/ 13 декабря 2011
var OBJ = (function(){
    var privateVar = 23;
    var self = {
        thePrivateVar : function() {
          return privateVar;
        },  

        thePrivateVarTimeout : function() {
            setTimeout(function() { alert(self.thePrivateVar); } , 10);
        }
    };

    return self;

}());

this === global || undefined внутри вызываемой функции.В ES5 это то, чем является глобальная среда, в строгом ES5 оно не определено.

Более распространенные шаблоны включают использование var that = this в качестве локального значения в функции

var obj = (function() {
  var obj = {
    property: "foobar",
    timeout: function _timeout() {
      var that = this;
      setTimeout(alertData, 10);

      function alertData() {
        alert(that.property);
      }
    }
  }

  return obj;
}());

или использование.bindAll метод

var obj = (function() {
  var obj = {
    alertData: function _alertData() {
      alert(this.property);
    }
    property: "foobar",
    timeout: function _timeout() {
      setTimeout(this.alertData, 10);
    }
  }

  bindAll(obj)

  return obj;
}());


/*
    bindAll binds all methods to have their context set to the object

    @param Object obj - the object to bind methods on
    @param Array methods - optional whitelist of methods to bind

    @return Object - the bound object
*/
function bindAll(obj, whitelist) {
    var keys = Object.keys(obj).filter(stripNonMethods);

    (whitelist || keys).forEach(bindMethod);

    function stripNonMethods(name) {
        return typeof obj[name] === "function";
    }

    function bindMethod(name) {
        obj[name] = obj[name].bind(obj);
    }

    return obj;
}
...