您可以在JavaScript中的私有方法中访问对象定义的属性吗?

时间:2013-10-15 04:36:05

标签: javascript

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

$.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始终是我的处理程序中的默认值(空字符串)
  5. 无序的地方是我定义属性的地方 - 在对象的其余部分之后。就好像我在定义一个试图引用属性的方法之后我正在改变对象的原型......这不可能是正确的。

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

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

    有没有办法提前注册房产?

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

1 个答案:

答案 0 :(得分:5)

因为this中的this._currentUser = username;不符合您的想法。 JavaScript中this的值取决于函数的调用方式。我假设在处理程序中,它现在指的是hubProxycollidR以外的其他一些对象。

假设您的整个插件this引用collidR (我非常怀疑不是,在此后的部分中有解释),您可以做的就是保存该范围的上下文转换为另一个变量 outside 处理程序。这样,您可以通过该变量引用外部范围的上下文:

// 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)和you are attaching some property to the library。将插件特定值附加到全局库是有风险的,因为可能会发生冲突。

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