构造函数内的事件处理

时间:2015-03-20 00:15:03

标签: javascript events closures private

我真的很抱歉,但我无法弄清楚它为什么不起作用。 printStr()可以访问仅在Foo构造函数中定义的变量,但不能访问在mousedown事件中触发的私有函数中定义的变量。有没有办法在没有在string func中声明printStr的情况下访问getBotheredByBrendanEich

function Foo(elem) {
  elem.on('mousedown', getBotheredByBrendanEich);

  function getBotheredByBrendanEich() {
    var string = 'its just werks!';
    elem.on('mouseup', printStr);
  }

  function printStr() {
    console.log(string);
  }
}

var test = new Foo($('#test'));

1 个答案:

答案 0 :(得分:1)

您的变量string是函数get...()内的局部变量,并且仅在该范围内可用。局部变量仅在声明它们的函数中可用,在本例中是get...()函数

如果您希望它在更广泛的范围内可用,以便printStr()可以使用它,那么您必须在更高的范围内声明它。

您可以使用在同一范围内声明的匿名函数来解决此问题:

function Foo(elem) {
  elem.on('mousedown', getBotheredByBrendanEich);

  function getBotheredByBrendanEich() {
    var str = 'its just werks!';
    elem.on('mouseup', function() {
      console.log(str);
    });
  }
}

var test = new Foo($('#test'));

或者,您可以使用.bind()将参数传递给事件处理程序:

function Foo(elem) {
  elem.on('mousedown', getBotheredByBrendanEich);

  function getBotheredByBrendanEich() {
    var string = 'its just werks!';
    elem.on('mouseup', printStr.bind(this, string));
  }

  function printStr(arg) {
    console.log(arg);
  }
}

var test = new Foo($('#test'));

或者,您可以将变量移动到更高的范围,以便可以共享:

function Foo(elem) {
  elem.on('mousedown', getBotheredByBrendanEich);

  var str = 'its just werks!';

  function getBotheredByBrendanEich() {
    elem.on('mouseup', printStr);
  }

  function printStr() {
    console.log(str);
  }
}

var test = new Foo($('#test'));

但是在所有情况下,这种结构很麻烦,因为每次发生mousedown事件时都会添加一个新的mouseup事件处理程序。这意味着只需点击几下即可获得多个鼠标处理程序。这很少是你真正想做的事情。

我建议不会遇到这个问题:

function Foo(elem) {
  var str = 'its just werks!';

  elem.on('mousedown', function() {
      // whatever code you want here
  });
  elem.on('mouseup', function() {
      console.log(str);
  });
}

var test = new Foo($('#test'));

还有一条评论。您的代码没有显示在此处实际使用构造函数的任何理由。看起来您可以实现正常的函数调用,因为没有对象实例数据。