为什么我的简单事件处理示例不起作用?

时间:2011-11-23 09:46:58

标签: javascript scope

我正在尝试创建一个简单的事件处理程序。

(注意,我不是要尝试实现一个完整的发布/订阅模型;我只是对我的示例不能正常工作的原因感兴趣)

var myObj = (function () {

  var private = "X";

  function triggerEvent(eventName) {
    if (this[eventName]) {
      this[eventName]();
    }
  }

  // Setter / Getter
  function getProp() {
    return private;
  }

  function setProp(value) {
    private = value;
    triggerEvent("onPropChange");
  }

  // Public API
  return {
    // Events
    "onPropChange": null,    // Fires when prop value is changed

    // Methods
    "getProp": getProp,
    "setProp": setProp
  };
})();

// Now set event handler
myObj.onPropChange = function () {
  alert("You changed the property!");
};

myObj.setProp("Z");  // --> Nothing happens. Wrong
                     // Why doesn't my alert show?

我将对象的onPropChange属性设置为更简单的处理函数,但它没有被触发。我调试了这个,似乎在triggerEvent中变量this引用了全局window对象。我认为它应该引用myObj(这就是我需要的)。

有人可以解释我的想法中的错误以及我如何纠正这个错误?非常感谢。

jsFiddle here

1 个答案:

答案 0 :(得分:2)

更改您的代码,以便创建obj,然后像这样返回:

var myObj = (function () {

  var private = "X";
  var obj = {
    "onPropChange": null,    // Fires when prop value is changed

    // Methods
    "getProp": getProp,
    "setProp": setProp
  };

  function triggerEvent(eventName) {
    if (obj[eventName]) {
      obj[eventName]();
    }
  }

  // Setter / Getter
  function getProp() {
    return private;
  }

  function setProp(value) {
    private = value;
    triggerEvent("onPropChange");
  }

  return obj;          
})();

通过这种方式,您可以引用私有函数的对象。

固定小提琴 - http://jsfiddle.net/infernalbadger/dkqUW/2/

另一种修复它的方法是使用.call函数:

function setProp(value) {
    private = value;
    triggerEvent.call(this, "onPropChange");
}

这指定了this在被调用方法(triggerEvent)中的含义。

http://jsfiddle.net/infernalbadger/dkqUW/3/