';这';在JavaScript类方法中未定义

';这';在JavaScript类方法中未定义,javascript,class,prototype,Javascript,Class,Prototype,我是JavaScript新手。据我所知,它的新功能是调整现有代码并编写少量jQuery 现在我正试图用属性和方法编写一个“类”,但在方法方面遇到了问题。我的代码: function Request(destination, stay_open) { this.state = "ready"; this.xhr = null; this.destination = destination; this.stay_open = stay_open; this.

我是JavaScript新手。据我所知,它的新功能是调整现有代码并编写少量jQuery

现在我正试图用属性和方法编写一个“类”,但在方法方面遇到了问题。我的代码:

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.start
中,
未定义,因此if语句的计算结果为false。我做错了什么

如何调用start函数

这应该会起作用(新建是关键)

如果您像
Request.prototype.start()
那样直接调用它,
这将引用全局上下文(
浏览器中的窗口

此外,如果
未定义此
,则会导致错误。if表达式的计算结果不为false

更新
对象不是根据声明设置的,而是通过调用设置的。这意味着,如果将函数属性分配给变量,如
x=o.start
并调用
x()
内部start不再指
o
。这是执行
setTimeout
时发生的情况。要使其工作,请改为执行以下操作:

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

JavaScript的OOP有点古怪(或很多),需要一些时间才能习惯。你需要记住的第一件事是,没有课程,按课程来思考会让你绊倒。为了使用附加到构造函数(类定义的JavaScript等价物)的方法,需要实例化对象。例如:

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

enemyNinja = new Ninja('boggis');
enemyNinja.name; //=> 'boggis'
请注意,
Ninja
实例具有相同的属性,但
aNinja
无法访问
enemyNinja
的属性。(这部分应该非常简单/直接)当您开始向
原型添加内容时,情况会有所不同:

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

直接调用此操作将引发错误,因为当实例化构造函数时,只指向正确的对象(您的“类”),否则指向浏览器中的全局对象,
window

在ES2015 a.k.a ES6,
Class
函数的语法糖

如果您想强制设置
的上下文,可以使用
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>
    );
  }
}
类表单扩展了React.Component{
构造函数(){
超级();
}
手变(e){
开关(如target.id){
案例“所有者”:
this.setState({owner:e.target.value});
打破
违约:
}
}
render(){
返回(
所有者:

); } }

在这里,我们将
handleChange()
中的上下文强制为
形式

我只想指出,有时发生此错误是因为函数被用作高阶函数(作为参数传递),然后
的范围丢失。在这种情况下,我建议将这样的函数绑定到
this
。例如

this.myFunction.bind(this);

这个问题已经得到了回答,但也许有人会来这里

我还遇到了一个问题,
这个
是未定义的,当时我愚蠢地试图在初始化类时分解类的方法:

从“/MyClass”导入MyClass
//此处未定义“this”:
const{aMethod}=new MyClass()
aMethod()//错误:未定义“this”
//因此,与通常情况下一样,使用init:
const myClass=new myClass()
myClass.aMethod()//确定
使用箭头功能:

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

    }
};

以前的答案都没有完整的解决方案,所以把我的答案贴在这里

我有一个类,当我在方法引用上运行
forEach
时,它返回了一个错误

e、 g

class-Foo{
你好(姓名){
返回'hello${name}`
}
多格里特(姓名){

返回console.log(this.hello(name))//在
prototype
中有
start
的原因吗?
请求是什么。prototype
设置为?我在这里有一个类似的问题:其中有很多有用的链接。关键是JavaScript中的
this
不是一个对被调用的原型函数的“所有者”的恒定引用,就像uld可以使用大多数面向对象语言,如Java。@Matt:Request是一个构造函数。Request.prototype默认为
new Object()
。添加到其中的任何内容都会自动成为使用
new Request()创建的对象的属性
。我的意思是,这个问题被问到的时间比这个问题晚了3年。我正在使用setTimeout:
var listen=new Request(destination,stay_open);setTimeout(listen.start,500);
这救了我的命,因为我试图理解为什么我传递给express的函数“不能使用相同的输出。或者执行
o.start.bind(o)
。为什么
x=o.start;x()
不起作用?
.bind()
返回一个新函数,但不在适当位置工作。因此,您必须执行
x=o.start.bind(o);x()
o.start=o.start.bind(o);x=o.start;x()
您应该在构造函数中将函数绑定到它。否则,您将在每次调用
render
时绑定它,而不是在实例化类时调用一次。此外,您的大多数示例实际上与问题无关。或者在定义
handleChange()时使用箭头语法
很好的解释!!这正是我想要的。不知道你刚才帮我省了多少麻烦。为什么
这个
的范围丢失了?好问题!我希望这有帮助:谢谢。这是正确的答案!为什么不接受?
Request.prototype.start = () => {
    if( this.stay_open == true ) {
        this.open({msg: 'listen'});
    } else {

    }
};