97 votes

'ceci' n'est pas défini dans les méthodes de classe JavaScript

Je suis nouveau en JavaScript. Nouveau dans la mesure où tout ce que j'ai vraiment fait avec, c'est peaufiner le code existant et écrire de petits morceaux de jQuery.

Maintenant, j'essaie d'écrire une "classe" avec des attributs et des méthodes, mais j'ai des problèmes avec les méthodes. Mon code :

 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

Le problème est que, dans Request.prototype.start , this n'est pas défini et donc l'instruction if est évaluée à false. Qu'est-ce que je fais de mal ici ?

70voto

EliuX Points 4416

Je voulais juste souligner que parfois cette erreur se produit parce qu'une fonction a été utilisée comme fonction d'ordre élevé (passée comme argument) et que la portée de this été perdue. Dans de tels cas, je recommanderais de passer cette fonction liée à this . Par exemple

 this.myFunction.bind(this);

6voto

Nick G Points 1689

Aucune des réponses précédentes n'avait la solution complète pour moi, alors postez la mienne ici.

J'avais une classe qui renvoyait une erreur lorsque j'exécutais forEach sur la référence de méthode.

par exemple

 class Foo {
  hello (name) {
    return `hello ${name}`
  }

  doGreet (name) {
    return console.log(this.hello(name)) // <- 'this' is undefined
  }
}

// print some names...
const foo = new Foo();
(['nick', 'john']).forEach(foo.doGreet)

// TypeError: Cannot read property 'hello' of undefined
//     at doGreet (/.../test.js:7:17)

La solution consistait à lier le contexte des this de la méthode au sein d'un constructeur. c'est à dire

 class Foo {
  constructor () {
    this.doGreet = this.doGreet.bind(this)
  }

  // ... yada yada ...
}

5voto

Nitin Points 89

Dans ES2015 aka ES6, class est un sucre syntaxique pour functions .

Si vous souhaitez forcer à définir un contexte pour this vous pouvez utiliser la méthode bind() Comme @chetan l'a souligné, lors de l'invocation, vous pouvez également définir le contexte ! Vérifiez l'exemple ci-dessous :

 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>
    );
  }
}

Ici, nous avons forcé le contexte à l'intérieur de handleChange() à Form .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X