Comment accéder correctement à cet objet dans la fonction de rappel
P粉608647033
P粉608647033 2023-08-20 16:11:32
0
2
573
<p>J'ai un constructeur qui enregistre un gestionnaire d'événements : </p> <p><br /></p> <pre class="snippet-code-js lang-js Prettyprint-override"><code>function MyConstructor(data, transport) { this.data = données ; transport.on('données', fonction () { alerte (this.data); }); } //Simuler l'objet de transfert var transport = { sur : fonction (événement, rappel) { setTimeout(rappel, 1000); } } ; // Méthode d'appel var obj = new MyConstructor('foo', transport);</code></pre> <p><br /></p> <p>Cependant, dans la fonction de rappel, je ne peux pas accéder aux propriétés <code>data</code> Il semble que <code>this</code> ne pointe pas vers l'objet créé, mais vers un autre objet. </p> <p>J'ai également essayé d'utiliser des méthodes objet au lieu de fonctions anonymes : </p> <pre class="brush:php;toolbar:false;">function MyConstructor(data, transport) { this.data = données ; transport.on('data', this.alert); } MonConstructor.prototype.alert = function() { alert(ce.nom); };</pré> <p>Mais il y avait aussi le même problème. </p> <p>Comment accéder au bon objet ? </p>
P粉608647033
P粉608647033

répondre à tous(2)
P粉921130067

Voici quelques façons d'accéder au contexte parent dans le contexte enfant :

  1. Vous pouvez utiliser la fonction bind().
  2. Stockez une référence à context/this dans une autre variable (voir exemple ci-dessous).
  3. Utilisez la fonction flèche de ES6.
  4. Modifiez le code, la conception des fonctions 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) );
}
// 模拟传输对象
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// 调用方式
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 du 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);
  });
}
P粉176151589

Connaissances sur this

this (également appelé « contexte ») est un mot-clé spécial à l'intérieur de chaque fonction dont la valeur dépend uniquement de la manière dont la fonction est appelée, et non de la manière dont elle est définie. Elle n'est pas affectée par la portée lexicale, contrairement aux autres variables (sauf les fonctions fléchées, voir ci-dessous). Voici quelques exemples :

function foo() {
    console.log(this);
}

// 普通函数调用
foo(); // `this` 将引用 `window`

// 作为对象方法
var obj = {bar: foo};
obj.bar(); // `this` 将引用 `obj`

// 作为构造函数
new foo(); // `this` 将引用从 `foo.prototype` 继承的对象

Pour en savoir plus sur this, veuillez vous référer à la Documentation MDN.


Comment citer correctement this

Utilisez les fonctions fléchées

ECMAScript 6 a introduit les fonctions fléchées, qui peuvent être considérées comme des fonctions lambda. Ils n'ont pas leurs propres this绑定。相反,this在作用域中查找,就像普通变量一样。这意味着你不需要调用.bind fixations. 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. Ils ont également d'autres comportements spéciaux, consultez la documentation MDN pour plus d'informations.

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

this,而是需要访问它所指的对象。因此,一个简单的解决方案是创建一个新变量,也指向该对象。变量可以有任何名称,但常见的是selfthatEn fait, vous n'avez pas besoin d'accéder spécifiquement à

, mais plutôt à l'objet auquel il fait référence. Une solution simple consiste donc à créer une nouvelle variable qui pointe également vers 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);
    });
}
self是一个普通变量,它遵循词法作用域规则,并且可以在回调函数内部访问。这还有一个优点,即可以访问回调函数本身的thisPuisque self est une variable normale, elle suit les règles de portée lexicale et est accessible dans la fonction de rappel. Cela présente également l'avantage d'avoir accès à la valeur de la fonction de rappel elle-même.

thisDéfinition explicite de la fonction de rappel

- Partie 1

thisIl peut sembler que vous n'avez aucun contrôle sur la valeur de

puisque sa valeur est automatiquement définie, mais ce n'est pas réellement le cas.

Chaque fonction a une méthode .bind [文档],它返回一个将this绑定到一个值的新函数。该函数的行为与你调用.bind时的函数完全相同,只是this由你设置。无论如何或何时调用该函数,this.bind

[docs]this绑定到MyConstructorthis

, qui renvoie une nouvelle fonction qui lie à une valeur. Le comportement de cette fonction est exactement le même que lorsque vous appelez .bind, sauf qu'il est défini par vous. Peu importe le moment où la fonction est appelée, fera toujours référence à la valeur transmise.

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // 括号不是必需的
        alert(this.data);             // 但可能提高可读性
    }).bind(this); // <- 这里我们调用了`.bind()`
    transport.on('data', boundFunction);
}
jQuery.proxyDans ce cas, nous lions le de la fonction de rappel à la valeur de MyConstructor. Remarque :

Pour le contexte de liaison de jQuery, utilisez 🎜🎜 🎜🎜[Documentation]🎜🎜🎜. La raison en est qu'il n'est pas nécessaire de stocker une référence à la fonction lors de la dissociation du rappel d'événement. jQuery gère cela en interne. 🎜

Configurer la fonction de rappelthis - Partie 2

Certaines fonctions/méthodes qui acceptent une fonction de rappel acceptent également une valeur qui doit être utilisée comme this。这与手动绑定相同,但是函数/方法会为你执行绑定。例如,Array#map de la fonction de rappel. C'est la même chose que la liaison manuelle, mais la fonction/méthode effectue la liaison pour vous. Par exemple, Array#map code > [Documentation]C'est la méthode. Sa signature est :

array.map(callback[, thisArg])

Le premier paramètre est la fonction de rappel et le deuxième paramètre est la valeur à laquelle thisdevrait 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); // <- 这里我们将`obj`作为第二个参数传递

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


[Documentation]

Description Une option appelée context :

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

this.method被分配为点击事件处理程序,但是如果点击document.body,记录的值将是undefined,因为在事件处理程序内部,this指的是document.body,而不是FooUne autre manifestation courante de ce problème est l'utilisation de méthodes objet comme rappels/gestionnaires d'événements. En JavaScript, les fonctions sont des citoyens de première classe, et le terme « méthode » fait simplement référence à une fonction qui est la valeur de la propriété d'un objet. Mais il n'existe pas de lien spécifique entre la fonction et son objet "contenant".
thisConsidérons l'exemple suivant :

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

Foo.prototype.method = function() {
    console.log(this.data);
};
La fonction this.method est assignée comme gestionnaire d'événements de clic, mais si vous cliquez 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 à une instance de Foo. Comme mentionné précédemment,
fait référence à la façon dont une fonction

est appelée

, et non à la façon dont est définie . .bindthis Cela pourrait être plus évident si le code ressemble à ceci :

function method() {
    console.log(this.data);
}


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

Foo.prototype.method = method;

🎜La solution 🎜 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 en utilisant la fonction anonyme comme rappel/événement
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal