Maison > Questions et réponses > le corps du texte
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粉3114235942023-10-12 09:02:51
绑定 a>()
. bind()
fonctionfunction 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));
function MyConstructor(data, transport) {
var self = this;
this.data = data;
transport.on('data', function() {
alert(self.data);
});
}
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => {
alert(this.data);
});
}
P粉9680081752023-10-12 00:55:03
此内容您应该了解
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.
this
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,
.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
,而是访问它引用的对象。这就是为什么一个简单的解决方案是简单地创建一个也引用该对象的新变量。变量可以有任何名称,但常见的是 self
和 that
Vous ne souhaitez pas réellement accéder à
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); }); }
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
.bind
this
绑定到 MyConstructor
的 this
this
- Partie 2Certaines 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
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 défini .
Il pourrait être plus évident que la fonction n'a aucune référence implicite à l'objet si le code ressemble à ceci : .bind
将this
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
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();