1

我正在构建一个大致如下布局的库。有几个变量,一个事件处理程序和一个导致相关事件触发的方法。最后,我延长了与财产的交易。它是这样的(我已经添加了一些///...我已经剪掉了其他代码的地方):

$.collidR = function (options) {

  /// ...

  var hubName = 'CollidRHub';
  var hubProxy = connection.createHubProxy(hubName);   

  /// ...

  hubProxy.on('registrationComplete', function (username, hasChanges) {
      $(window).triggerHandler(events.onRegistrationComplete, { username: username, hasChanges: hasChanges });
      log(username + " has successfully registered for this entity.");

      // capture current user 
      this._currentUser = username;

      // hook for catching up when user joins after edits
      if (hasChanges) {
          log("There are outstanding changes for this entity...");

      }
  }); 

  /// ...

  this.registerClient = function () {
      /// does some stuff that makes registrationComplete fire
      /// ...
  };

};

Object.defineProperty($.collidR.prototype, "currentUser", {
    get: function () {
        return this._currentUser ? this._currentUser : "";
    }
});

请注意,上面的this._currentUser = username位似乎不起作用。我认为这是封装的问题,这就是这个问题的目标。

在一个单独但相关的库中,我创建了一个 的实例collidR,并且我需要响应一个事件。我有该设置的处理程序,如下所示:

$(window).on(collidR.events.onEditorsUpdated, function (e, data) {

  /// ...

  users.forEach(function (user) {
      var currentUser = collidR.currentUser;

      // here, currentUser is always default of ""
      if (user != currentUser) {
          /// ...
      }
  });

});

这是我所看到的:

  1. 我的registrationComplete事件触发并且处理程序被成功调用
  2. 来自调试器,this._currentUser在设置值之前未定义
  3. 执行该行this._currentUser = username并设置值
  4. onEditorsUpdated事件触发时,collidR.currentUser始终是我的处理程序中的默认值(空字符串)

感觉乱序的是我定义属性的位置——在对象的其余部分之后。就好像我在定义一个尝试引用该属性的方法之后更改了对象的原型......这不可能。

我也尝试过this.currentUser(在内部方法中),但结果相同。

我假设如果在调用内部方法之前扩展原型,那么当我这样做时var currentUser = collidR.currentUser;,我会从属性中获取值,但它始终是一个空字符串。

有没有办法提前登记房产?

是否有正确的方法来设置该值,以便我以后可以通过暴露的属性访问它?

4

1 回答 1

5

因为thisinthis._currentUser = username;不是你想的那样。JavaScript 中的值this取决于函数的调用方式。我假设在处理程序内部,它现在指的是.hubProxy以外的其他对象collidR

假设您的整个插件this引用了collidR(我高度怀疑不是,在后面的部分中解释),您可以做的是将该范围的上下文保存到处理程序之外的另一个变量中。这样,您可以通过该变量引用外部范围的上下文:

// Saving this scope's context
var that = this;

hubProxy.on('registrationComplete', function (username, hasChanges) {

  // access _currentUser via the saved context
  that._currentUser = username;

});

但是,我应该警告您不要使用this. 假设你正在创建一个插件,你会像$.collidR({..}). 在这种情况下,this函数内部将引用$(我假设是 jQuery),并且您将一些属性附加到 library。将特定于插件的值附加到全局库是有风险的,因为可能会发生冲突。

我建议您将其存储在局部变量/对象中。

于 2013-10-15T04:40:53.933 回答