Maison  >  Questions et réponses  >  le corps du texte

Comment accéder au correct "ceci" dans le rappel

J'ai un constructeur qui enregistre les gestionnaires d'événements :


function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', function () {
        alert(this.data);
    });
}

// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};

// called as
var obj = new MyConstructor('foo', transport);


Cependant, je ne parviens pas à accéder à l'objet créé à l'intérieur du callback data 属性。看起来 this qui ne fait pas référence à l'objet créé mais à un autre objet.

J'ai également essayé d'utiliser des méthodes objet au lieu de fonctions anonymes :

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', this.alert);
}

MyConstructor.prototype.alert = function() {
    alert(this.name);
};

Mais il a aussi le même problème.

Comment accéder au bon objet ?

P粉296080076P粉296080076374 Il y a quelques jours532

répondre à tous(2)je répondrai

  • P粉311423594

    P粉3114235942023-10-12 09:02:51

    Voici quelques façons d'accéder au contexte parent dans le contexte enfant -
    1. Vous pouvez utiliser la fonction 绑定().
    2. Stockez une référence à context/this dans une autre variable (voir exemple ci-dessous).
    3. Utilise la fonctionnalité ES6 flèches.
    4. Changer le code, la conception fonctionnelle et l'architecture - pour cela, vous devez maîtriser les Design Patterns en JavaScript.

    1.Utilisez la bind()fonction

    function MyConstructor(data, transport) {
        this.data = data;
        transport.on('data', ( function () {
            alert(this.data);
        }).bind(this) );
    }
    // Mock transport object
    var transport = {
        on: function(event, callback) {
            setTimeout(callback, 1000);
        }
    };
    // called as
    var obj = new MyConstructor('foo', transport);
    

    Si vous utilisez Underscore.js - http://underscorejs.org/#bind

    transport.on('data', _.bind(function () {
        alert(this.data);
    }, this));

    2. Stockez la référence au contexte/this dans une autre variable

    function MyConstructor(data, transport) {
      var self = this;
      this.data = data;
      transport.on('data', function() {
        alert(self.data);
      });
    }
    

    3.Fonction flèche

    function MyConstructor(data, transport) {
      this.data = data;
      transport.on('data', () => {
        alert(this.data);
      });
    }
    

    répondre
    0
  • P粉968008175

    P粉9680081752023-10-12 00:55:03

    À propos此内容您应该了解

    this (alias "contexte") est un mot-clé spécial dans chaque fonction dont la valeur dépend uniquement de comment la fonction est appelée, et non de comment/quand/où elle est définie. Elle n'est pas affectée par la portée lexicale comme les autres variables (sauf les fonctions fléchées, voir ci-dessous). Voici quelques exemples :

    function foo() {
        console.log(this);
    }
    
    // normal function call
    foo(); // `this` will refer to `window`
    
    // as object method
    var obj = {bar: foo};
    obj.bar(); // `this` will refer to `obj`
    
    // as constructor function
    new foo(); // `this` will refer to an object that inherits from `foo.prototype`

    Pour en savoir plus sur , consultez la Documentation MDN.


    Comment citer correctementthis

    Utilisez les fonctions fléchées

    ECMAScript 6 introduit des fonctions fléchées, qui peuvent être considérées comme des fonctions lambda. Ils n'ont pas leur propre reliure this 绑定。相反,this 就像普通变量一样在范围内查找。这意味着您不必调用 .bind. Au lieu de cela,

    est recherché dans la portée, tout comme une variable normale. Cela signifie que vous n'avez pas besoin d'appeler .bind. Ce n'est pas leur seul comportement spécial, consultez la documentation MDN pour plus d'informations.

    function MyConstructor(data, transport) {
        this.data = data;
        transport.on('data', () => alert(this.data));
    }
    这个Ne pas utiliser

    this,而是访问它引用的对象。这就是为什么一个简单的解决方案是简单地创建一个也引用该对象的新变量。变量可以有任何名称,但常见的是 selfthatVous ne souhaitez pas réellement accéder à

    spécifiquement, mais

    accéder à l'objet auquel il fait référence self 是一个普通变量,因此它遵循词法范围规则并且可以在回调内部访问。这还有一个优点,即您可以访问回调本身的 this. C'est pourquoi une solution simple consiste simplement à créer une nouvelle variable qui fait également référence à l'objet. Les variables peuvent avoir n'importe quel nom, mais les plus courants sont self et that.

    function MyConstructor(data, transport) {
        this.data = data;
        var self = this;
        transport.on('data', function() {
            alert(self.data);
        });
    }

    Puisque self est une variable normale, elle suit les règles de portée lexicale et est accessible dans le rappel. Cela présente également l'avantage que vous pouvez accéder à la valeur this du rappel lui-même.

    Définition explicite des rappels this - Partie 1

    Il peut sembler que vous n'avez aucun contrôle sur la valeur de puisque sa valeur est définie automatiquement, mais ce n'est pas réellement le cas. .bind [docs],它返回一个新函数,其中 this 绑定到一个值。该函数与您调用 .bind 的函数具有完全相同的行为,只是 this 是由您设置的。无论何时或如何调用该函数,this

    Chaque fonction a la méthode

    .bind this 绑定到 MyConstructorthis

    [docs]

    , qui renvoie une nouvelle fonction où est lié à une valeur. Cette fonction a exactement le même comportement que la fonction que vous appelez .bind, sauf que le jQuery .proxy est défini par vous. Peu importe quand et comment la fonction est appelée, fera toujours référence à la valeur transmise.

    function MyConstructor(data, transport) {
        this.data = data;
        var boundFunction = (function() { // parenthesis are not necessary
            alert(this.data);             // but might improve readability
        }).bind(this); // <- here we are calling `.bind()` 
        transport.on('data', boundFunction);
    }
    Dans cet exemple, nous lions les du rappel à la valeur des de MyConstructor.

    🎜🎜Remarque : 🎜Lors de la liaison du contexte à jQuery, utilisez plutôt 🎜🎜 🎜🎜[docs]🎜🎜🎜. La raison en est que vous n'avez pas besoin de stocker une référence à la fonction lors de la dissociation du rappel d'événement. jQuery gère cela en interne. 🎜

    Configuration des rappels this - Partie 2

    Certaines fonctions/méthodes qui acceptent un rappel acceptent également une valeur à laquelle le rappel this 应该引用的值。这与您自己绑定它基本上相同,但是函数/方法会为您完成它。 Array#map doit faire référence. C'est fondamentalement la même chose que de le lier vous-même, mais la fonction/méthode le fait pour vous. Array#map < em> [docs]C'est la méthode. Sa signature est :

    array.map(callback[, thisArg])

    Le premier paramètre est le rappel et le deuxième paramètre est la valeur this doit faire référence. Voici un exemple artificiel :

    var arr = [1, 2, 3];
    var obj = {multiplier: 42};
    
    var new_arr = arr.map(function(v) {
        return v * this.multiplier;
    }, obj); // <- here we are passing `obj` as second argument

    Remarque : la question de savoir si peut recevoir une valeur pour this 传递值通常在该函数/方法的文档中提到。例如, jQuery 的 $.ajax 方法 [docs] 描述了一个名为 context est généralement mentionnée dans la documentation de cette fonction/méthode. Par exemple, la la méthode $.ajax de jQuery

    [docs]

    décrit une option appelée context :

    FAQ : Utiliser des méthodes d'objet comme rappels/gestionnaires d'événements

    Une autre manifestation courante de ce problème est lorsqu'une méthode objet est utilisée comme gestionnaire de rappel/d'événement. Les fonctions sont des citoyens de première classe en JavaScript, et le terme « méthode » n'est qu'un terme familier désignant une fonction, qui est la valeur de la propriété d'un objet. Mais la fonction n'a pas de lien spécifique vers son objet "contenant". this.method被指定为点击事件处理程序,但如果点击document.body,记录的值将是未定义,因为在事件处理程序中,this 引用的是 document.body,而不是 Foo
    Considérons l'exemple suivant : this

    function Foo() {
        this.data = 42,
        document.body.onclick = this.method;
    }
    
    Foo.prototype.method = function() {
        console.log(this.data);
    };
    La fonction this.method est spécifiée comme gestionnaire d'événements de clic, mais si l'on clique sur document.body, la valeur enregistrée sera non définie car Dans le gestionnaire d'événements, fait référence à document.body, et non à l'instance de Foo. Comme déjà mentionné au début, ce à quoi fait référence dépend de la façon dont la fonction
    est appelée

    , et non de la façon dont

    est défini . Il pourrait être plus évident que la fonction n'a aucune référence implicite à l'objet si le code ressemble à ceci : .bindthis

    function method() {
        console.log(this.data);
    }
    
    
    function Foo() {
        this.data = 42,
        document.body.onclick = this.method;
    }
    
    Foo.prototype.method = method;

    La solution this est la même que celle mentionnée ci-dessus : utilisez .bind pour lier explicitement

    à une valeur spécifique

    si disponible

    document.body.onclick = this.method.bind(this);

    Ou appelez explicitement la fonction en tant que "méthode" de l'objet en utilisant une fonction anonyme comme gestionnaire de rappel/événement et affectez l'objet (🎜) à une autre variable : 🎜
    var self = this;
    document.body.onclick = function() {
        self.method();
    };
    🎜ou utilisez la fonction flèche : 🎜
    document.body.onclick = () => this.method();

    répondre
    0
  • Annulerrépondre