Class.create和这个关键字

时间:2009-08-03 13:44:45

标签: javascript prototypejs

我正在尝试使用prototype.js的 Class 方法来管理我当前项目中的对象层次结构,但是我在使用 this 关键字时遇到了一些问题。与 Class.create 结合。

这是一段用于创建继承的老式普通js代码:

var Super1 = function () {
    this.fu = "bar";
}

var Sub1 = function () {
    this.baz = "bat";
    this.f = function (e) {
        alert("Sub1:"+this.fu+this.baz);
    }.bindAsEventListener(this);
    document.observe("click", this.f);
};
Sub1.prototype = new Super1();
new Sub1();

这是我第一次用 Class.create 来模仿这个:

var Super2 = Class.create({
    fu: "bar"
});

var Sub2 = Class.create(Super2, {
    baz: "bat",
    f: function (e) {
        alert("Sub2:"+this.fu+this.baz);
    }.bindAsEventListener(this),
    initialize: function () {
        document.observe("click", this.f);
    }
});
new Sub2();

到目前为止一切都很好......但当然它不起作用: f 绑定到窗口,而不是用 new <创建的对象绑定/ strong>即可。我发现的唯一方法是:

var Super3 = Class.create({
    fu: "bar"
});

var Sub3 = Class.create(Super3, {
    baz: "bat",
    f: function (e) {
        alert("Sub3:"+this.fu+this.baz);
    },
    initialize: function () {
        this.f = this.f.bindAsEventListener(this);
        document.observe("click", this.f);
    }
});
new Sub3();

但它真的很不优雅。我该怎么处理这个?

编辑(回复科林):

  • 我需要绑定 f 本身,以便我可以在 f 上调用 stopObserving (参见http://prototypejs.org/api/event/stopObserving

  • 每次我在侦听器中需要 this 时,我仍然需要 bindAsEventListener ,因为默认情况下这个是触发它的元素事件(见http://prototypejs.org/api/event/observe

  • 我还在等待googlegroup上的anwser :)我有点张贴在这里,看看我是否可以通过S.O获得更快的答案。

  • 我可以(也可能应该)使用 bind 而不是 bindAsEventListener 。我用后者来表明我正在听一个听众。它并没有改变绑定程序不优雅的事实。

2 个答案:

答案 0 :(得分:3)

你几乎得到了它,只是不需要重新声明this.f:

var Sub3 = Class.create(Super3, {
    baz: "bat",
    f: function () {
        alert("Sub3:"+this.fu+this.baz);
    },
    initialize: function () {
        document.observe("click", this.f.bindAsEventListener(this));
        // You could also use .bind(), since you don't pass any 
        // other arguments to f
    }
});

编辑:在回复您的评论时,您可以执行类似的操作(尽管它可以说是“丑陋”的例子):

var Sub3 = Class.create(Super3, {
    baz: "bat",
    initialize: function () {
        this.f = function () {
           alert("Sub3:"+this.fu+this.baz);
        }.bind(this);

        document.observe("click", this.f);
    }
});

现在你可以在this.f中使用stopObserving。当你需要重新注册监听器时,你可以再次使用this.f,因为它仍然被绑定到调用initialize时使用的相同实例。

答案 1 :(得分:0)

我对这方面不太清楚,但我认为答案是(未经测试):

var Sub3 = Class.create(Super3, {
  baz: "bat",
  f: function() {
    alert("Sub3:"+this.fu+this.baz);
  },
  initialize: function () {
    document.observe("click", this.f.bind(this));
  }
});

类安排初始化被称为新对象的对象方法,因此'this'指的是'initialize'中的新对象,所以你只需要将this.f绑定到它。

顺便说一句,几乎不需要bindAsEventListener:Event.observe(和Element.observe)无论如何都以事件作为第一个参数调用处理程序。

顺便提一下2,Prototype & Scriptaculous google group是一个非常有用的论坛。