将此对象存储在自定义私有变量中

时间:2015-02-25 18:03:42

标签: javascript jquery this global

我有这个js对象

var toggleItem = {

  attrData : '',
  toggleNew : '',
  toggleOld : '',
  //var self : this,

  init : function(){

    self = this;
    self.listener();
  },

  listener : function(){

    jQuery('.btn-save').click(function(){
      var current = this.id.split('_').pop();
      self.toggleNew = jQuery('.toggle-data-new_'+current).val();
      self.toggleOld = jQuery('.toggle-data-old_'+current).val();
      self.updateForm();
    });
   },

  updateForm : function(){

    jQuery('#toggle-product-form #new').val(self.toggleNew);
    jQuery('#toggle-product-form #old').val(self.toggleOld);
    jQuery('#toggle-product-form').submit();
  },

 }

在过去,我经常遇到this值被更改为我引用jQuery的任何元素的问题。在这种情况下,我想将this存储在名为self的新变量中。但重要的是self不会全球可用。

您将在我写入//var self : this,的对象顶部看到已注释掉的内容。这是因为在它前面放置var会在控制台中呈现此错误 - Unexpected identifier。但是,如果我将var部分删除,并将其放在init函数(它的全局)中,那么我现在遇到的问题就像我现在一样。

问题我希望它可以用于对象内部的所有内容而不在外面吗?

无论什么解决方案有效,我还计划应用于顶部声明的其他三个变量。

NB 我知道我可以使用对象的名称而不是自己,并将此全局放在与其他内容冲突的风险相对较小的情况下,但我确定必须有重新分配this值的方法,同时保持toggleItem对象内只能访问它(当前形式)。

3 个答案:

答案 0 :(得分:1)

您只需要listener功能中的自引用。试着这样做:

var toggleItem = {
  // all your other stuff...
  listener: function() {
    var self = this;
    jQuery('.btn-save').click(function(){
      var current = this.id.split('_').pop();
      self.toggleNew = jQuery('.toggle-data-new_'+current).val();
      self.toggleOld = jQuery('.toggle-data-old_'+current).val();
      self.updateForm();
    });
  }
};

修改:或者,您可以将对self的所有引用更改为toggleItem,因为这确实是您尝试访问的内容。如果您想在不将其置于全局范围内的情况下声明self一次,那么您可以使用模块模式中的一个。

var toggleItem = (function() {
  var self = {
    // other stuff...
    listener: function() {
      jQuery('.btn-save').click(function(){
        var current = this.id.split('_').pop();
        self.toggleNew = jQuery('.toggle-data-new_'+current).val();
        self.toggleOld = jQuery('.toggle-data-old_'+current).val();
        self.updateForm();
      });
    }
  };
  return self;
})();

这会创建一个封闭的范围,因此self不会泄漏,它会立即调用该函数,以便为toggleItem分配函数的返回值。

答案 1 :(得分:1)

将来,要将成员变量设为私有,您可以使用closure。这将防止变量泄漏到全局范围。

function toggleItem() {
  var self = this,
  attrData = '',
  toggleNew = '',
  toggleOld = '';

  function init(){
    self.listener();
  }

  function listener(){
    jQuery('.btn-save').click(function(){
      var current = this.id.split('_').pop();
      self.toggleNew = jQuery('.toggle-data-new_'+current).val();
      self.toggleOld = jQuery('.toggle-data-old_'+current).val();
      self.updateForm();
    });
   }

  function updateForm(){
    jQuery('#toggle-product-form #new').val(self.toggleNew);
    jQuery('#toggle-product-form #old').val(self.toggleOld);
    jQuery('#toggle-product-form').submit();
  }

  return init;
 }

var toggle = toggleItem();
toggle.init();

答案 2 :(得分:1)

我会按照迈克的建议,但是要完整的模块模式路线。这将允许你拥有"私人"如果您想收集任何常用功能,也可以使用。

使用此解决方案,我不会看到self变量的需要,除非您还有其他不能分享的内容。这里提供的封装,将所有收集的内容保存在一个函数中,并且您不会在对象上看到所有其他函数(这是将所有内容都放到全局范围内的一步,但你可以采取这一步骤。)

var toggleItem = (function () {
    var self = this,
        attrData,
        toggleNew,
        toggleOld,
        init,
        listener,
        updateForm;

    init = function () {
        // This will call the "listener" function without the need for
        // "self", however you can specify it if you want to.
        listener();
    };

    listener = function () {
        jQuery('.btn-save').click(function () {
            var current = this.id.split('_').pop();

            // Again, you shouldn't need "self", but add it 
            // if it will ease your mind.
            toggleNew = jQuery('.toggle-data-new_' + current).val();
            toggleOld = jQuery('.toggle-data-old_' + current).val();
            updateForm();
        });
    };

    updateForm = function () {
        jQuery('#toggle-product-form #new').val(self.toggleNew);
        jQuery('#toggle-product-form #old').val(self.toggleOld);
        jQuery('#toggle-product-form').submit();
    };

    return {
        init: init
        // Add the other functions if you need to access them from outside 
        // the script here, but from what you showed, you should be fine
    }
}());