关于使用jQuery悬停方法时的闭包?

时间:2014-12-19 11:59:05

标签: javascript jquery

我的代码:

function Demo (){
  this.name = 'abc';
  this.age = 20;
}

var demo = {
  init : function(){
    $('#test').hover(this.stop, this.start);
  },

  start: function(){
    //here is the error
    alert(this.name);
  }

  stop: function(){
    alert(this.age); // 'this' does not mean the Demo object, but $('#test') object.
  }
}

Demo.prototype = demo;
Demo.prototype.constructor = Demo;

(new Demo).init();

当触发$(' #test')的悬停事件时,将调用stop方法。然而,'这个'在该方法中没有指向演示对象,而是$(' #test')对象。因此,警报未定义。我需要访问Demo对象中的属性。 stop和start方法将在其他地方重用,所以我不喜欢将整个方法代码写入hover的参数。 我该如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

thisstart方法中的stop并不一定指向与this相同的init。这是因为它们是回调函数。如果要引用相同的对象上下文,请尝试以下操作:

var demo = {
  init : function(){
    $('#test').hover(this.stop.bind(this), this.start.bind(this));
  },

  start: function(){
    //here is the error
    alert(this.name);
  }

  stop: function(){
    alert(this.age); // 'this' does not mean the Demo object, but $('#test') object.
  }
}

使用bind会将this上下文传递给回调。 MDN docs for bind are here.

答案 1 :(得分:2)

JQuery在幕后使用apply来调用事件回调,这就是上下文发生变化的原因。

要缓解这种情况,您可以执行以下两项操作之一:

使用bind

var demo = {
  init : function(){
    $('#test').hover(this.stop.bind(this), this.start.bind(this));
  },

  start: function(){
    alert(this.name);
  }

  stop: function(){
    alert(this.age);
  }
}

直接调用该方法

var demo = {
  init : function(){
    // Closure here
    var self = this;
    $('#test').hover(function() {
        self.stop();
    }, function() {
        self.start();
    });
  },

  start: function(){
    alert(this.name);
  }

  stop: function(){
    alert(this.age);
  }
}

答案 2 :(得分:-1)

无JSON实现,允许您设置变量self

function Demo(){
  this.name = 'abc';
  this.age = 20;
}

Demo.prototype = new (function(){
    var self = this;

    this.init = function(){
      $('#test').hover(self.stop, self.start);
    }

    this.start = function(){
      //here is the error
      alert(self.name);
    }

    this.stop = function(){
      alert(self.age); // 'this' does not mean the Demo object, but $('#test') object.
    }
  })();

(new Demo()).init()

编辑: 我已经更新,以显示我的意思,而不使用var demo = {...}我试图做的不是使用Object Literal又名JSON样式,所以你可以支持原型内的变量