2010-10-25 74 views
42

我是JavaScript新手。就我所做的所有事情而言,新增了对现有代码的调整,并编写了一小部分jQuery。'this'在JavaScript类方法中未定义

现在我试图写一个“类”的属性和方法,但我遇到了方法的麻烦。我的代码:

function Request(destination, stay_open) { 
    this.state = "ready"; 
    this.xhr = null; 
    this.destination = destination; 
    this.stay_open = stay_open; 

    this.open = function(data) { 
     this.xhr = $.ajax({ 
      url: destination, 
      success: this.handle_response, 
      error: this.handle_failure, 
      timeout: 100000000, 
      data: data, 
      dataType: 'json', 
     }); 
    }; 

    /* snip... */ 

} 

Request.prototype.start = function() { 
    if(this.stay_open == true) { 
     this.open({msg: 'listen'}); 
    } else { 

    } 
}; 
//all console.log's omitted 

的问题是,在Request.prototype.startthis是不确定的,因此,如果语句评估为假。我在这里做错了什么?

+0

你在'prototype'中有'start'的原因吗? – xj9 2010-10-25 03:56:12

+0

什么是'Request.prototype'设置为? – 2010-10-25 03:57:19

+0

我不知道:S – 2010-10-25 04:00:19

回答

43

你是如何调用启动功能的?

这应该工作(是关键)

var o = new Request(destination, stay_open); 
o.start(); 

如果你直接调用它,Request.prototype.start()this将引用(在浏览器中window)全球范围内。如果this未定义,则会导致错误。 if表达式不计算为false。

更新this对象不是基于申报设立但调用。这意味着如果将函数属性分配给像x = o.start这样的变量,并且请拨x(),this里面的起点不再指o。这是当你做setTimeout时发生的情况。要做到这一点,请这样做:

var o = new Request(...); 
setTimeout(function() { o.start(); }, 1000); 
+0

我正在使用setTimeout:'var listen = new Request(destination,stay_open); setTimeout(listen.start,500);' – 2010-10-25 04:01:44

+0

是的,这是行不通的。我会更新我的答案。 – 2010-10-25 04:04:03

+0

非常好,谢谢 – 2010-10-25 04:10:26

15

JavaScript的面向对象有点时髦(或很多),它需要一些习惯。你需要记住的第一件事是没有类并且根据课程思考可能会让你失望。为了使用附加到构造函数的方法(类定义的JavaScript),你需要实例化你的对象。例如:

Ninja = function (name) { 
    this.name = name; 
}; 
aNinja = new Ninja('foxy'); 
aNinja.name; //-> 'foxy' 

enemyNinja = new Ninja('boggis'); 
enemyNinja.name; //=> 'boggis' 

注意Ninja实例具有相同的属性,但aNinja不能访问的enemyNinja属性。 (这部分应该是很容易/简单),事情变得有点不同的,当你开始增加东西向prototype

Ninja.prototype.jump = function() { 
    return this.name + ' jumped!'; 
}; 
Ninja.prototype.jump(); //-> Error. 
aNinja.jump(); //-> 'foxy jumped!' 
enemyNinja.jump(); //-> 'boggis jumped!' 

调用这个因为this仅指向正确的对象(你的“类直接将抛出一个错误“)在构造函数实例化时(否则它指向全局对象,window在浏览器中)

3

ES2015又名ES6,classfunctions的语法糖。

如果要强制设置this的上下文,可以使用bind()方法。正如@chetan指出的那样,在调用时也可以设置上下文!检查下面的例子:

class Form extends React.Component { 
constructor() { 
    super(); 
    } 
    handleChange(e) { 
    switch (e.target.id) { 
     case 'owner': 
     this.setState({owner: e.target.value}); 
     break; 
     default: 
    } 
    } 
    render() { 
    return (
     <form onSubmit={this.handleNewCodeBlock}> 
     <p>Owner:</p> <input onChange={this.handleChange.bind(this)} /> 
     </form> 
    ); 
    } 
} 

在这里,我们不得不里面handleChange()背景下Form