OOP和jQuery:如何用Deferred()初始化一个变量

OOP and jQuery: how to init a var with Deferred();

本文关键字:初始化 变量 一个 Deferred jQuery 何用 OOP      更新时间:2023-09-26

这是我的javascript代码它的目的只是为了教育。我正在学习js OOP和jquery

function App() {
this.deviceReadyDeferred = new $.Deferred();
this.init = function() {
    console.log ("Run");
    $.when(this.deviceReadyDeferred).then(this.run);
    document.addEventListener("click", this.onDeviceReady, false);
},
// NB: onDeviceReady non ha parametri evento
this.onDeviceReady = function() {
    console.log("deviceReady");
    this.deviceReadyDeferred.resolve();
},
this.run = function() {
    console.log("main");
}
}
app = new App();
app.init();

当我点击时,我收到

TypeError: this.deviceReadyDeferred is undefined

为什么?

  • 我没有收到'$'是未定义的,所以jQuery运行良好。
  • 我在win7的FF 19.0.2上运行jQuery 1.9.1

如何使用延迟到一个javascript对象?如何初始化和重用它?

编辑:

这段代码是工作的。所有的问题都出在我滥用this上。我是javascript的OOP新手。

function App() {
    var self = this;
    this.deviceReadyDeferred = new $.Deferred();
    this.init = function() {
        console.log ("Run");
        $.when(self.deviceReadyDeferred).then(self.run);
        $(document).on("click", self.onClick);
    },
    this.onClick = function() {
        console.log("deviceReady");
        self.deviceReadyDeferred.resolve();
    },
    this.run = function() {
        console.log("main");
    }
}
app = new App();
app.init();

this inside

this.onDeviceReady = function() {
    ...
}

与它之外的this不一样。jQuery有一种内置的方法,通过将数据传递给事件处理程序来解决这个问题。

function App() {
    this.deviceReadyDeferred = new $.Deferred();
    this.init = function () {
        console.log("Run");
        $.when(this.deviceReadyDeferred).then(this.run);
        $(document).on("click", { App: this }, this.onDeviceReady);
    },
    // NB: onDeviceReady non ha parametri evento
    this.onDeviceReady = function (e) {
        console.log("deviceReady");
        e.data.App.deviceReadyDeferred.resolve();
    },
    this.run = function () {
        console.log("main");
    }
}
app = new App();
app.init();
http://jsfiddle.net/6zAN7/17/

或者,更简单的是,如果你不需要支持IE8,使用本机方法(注意.bind(this)):

function App() {
    this.deviceReadyDeferred = new $.Deferred();
    this.init = function () {
        console.log("Run");
        $.when(this.deviceReadyDeferred).then(this.run);
        document.addEventListener("click", this.onDeviceReady.bind(this), false);
    },
    // NB: onDeviceReady non ha parametri evento
    this.onDeviceReady = function () {
        console.log("deviceReady");
        this.deviceReadyDeferred.resolve();
    },
    this.run = function () {
        console.log("main");
    }
}
app = new App();
app.init();
http://jsfiddle.net/6zAN7/18/

其他答案已经解释了原因,这是回调中this的值。解决这个问题的方法之一是创建一个绑定到特定this值的新函数:

document.addEventListener("click", this.onDeviceReady.bind(this), false);

如果本地没有bind,则需要一个shim

this.init = function() {
    console.log ("Run");
    var self = this;
    $.when(this.deviceReadyDeferred).then(self.run);
    document.addEventListener("click", self.onDeviceReady, false);
},

正如Kevin B所说,thisclick处理程序中是document,因为您首先将该事件绑定到document上。

解决这种情况的一个简单方法是使用$.proxy():
document.addEventListener("click", $.proxy(this.onDeviceReady, this), false);