Maison  >  Article  >  interface Web  >  Comprendre le mot-clé « this »

Comprendre le mot-clé « this »

PHPz
PHPzoriginal
2023-08-30 17:05:09964parcourir

Comprendre le mot-clé « this »

Lorsque vous créez une fonction, elle crée une portée nommée this 的关键字(在幕后),该关键字链接到函数运行的对象。换句话说,this qui peut être utilisée pour sa fonction, mais c'est une référence à l'objet que la fonction a comme propriété ou méthode.

Regardons les cody objets de l'article précédent :

Exemple : sample98.html

<!DOCTYPE html><html lang="en"><body><script>

	var cody = {
		living: true,
		age: 23,
		gender: 'male',
		getGender: function () { return cody.gender; }
	};

	console.log(cody.getGender()); // Logs 'male'.

</script></body></html>

Remarquez comment, à l'intérieur de la fonction getGender, nous accédons à la propriété gender en utilisant la notation par points (cody.gender) sur l'objet getGender 函数内部,我们如何在 cody 对象本身上使用点表示法 (cody.gender) 访问 gender 属性。可以使用 this 重写来访问 cody 对象,因为 this 指向 cody lui-même. L'objet

est accessible à l'aide de la substitution

car

pointe vers l'objet

. this.gender 中使用的 this

Exemple : sample99.html

<!DOCTYPE html><html lang="en"><body><script>

	var cody = {
		living: true,
		age: 23,
		gender: 'male',
		getGender: function () { return this.gender; }
	};

	console.log(cody.getGender()); // Logs 'male'.

</script></body></html>
this 的主题可能会令人困惑,但事实并非如此。请记住,一般来说, this 在函数内部使用来引用该函数所包含的对象,而不是函数本身(例外情况包括使用 new 关键字或 call()应用()

fait simplement référence à l'objet cody qui exploite la fonction.

this

).

Le arguments 和发送到函数的任何参数相反,thisMot-clé

ressemble et se comporte comme n'importe quelle autre variable, sauf que vous ne pouvez pas le modifier.

Contrairement aux arguments et à tous les arguments envoyés à une fonction, this sont des mots-clés (et non des propriétés) dans l'objet appelant/activant.

Comment est déterminée la valeur de this

?

myObject 对象被赋予一个名为 sayFoo 的属性,该属性指向 sayFoo 函数。当从全局范围调用 sayFoo 函数时,this 引用 window 对象。当作为 myObject 的方法调用时,this 指的是 myObjectLa valeur de

transmise à toutes les fonctions est basée sur le contexte dans lequel la fonction est appelée au moment de l'exécution. Faites attention ici, car c'est une de ces bizarreries dont vous devez simplement vous souvenir.

myObject 有一个名为 fooL'objet myObject dans l'exemple de code suivant se voit attribuer une propriété nommée sayFoo, qui pointe vers la fonction sayFoo. Lorsque la fonction sayFoo est appelée depuis la portée globale,

fait référence à l'objet

. Lorsqu'il est appelé comme méthode de myObject,

fait référence à myObject.

this 的值基于调用该函数的上下文。考虑 myObject.sayFoosayFoo 都指向相同的函数。但是,根据调用 sayFoo() 的位置(上下文),thisUtilisé en raison des propriétés de

.

windowExemple : sample100.html

<!DOCTYPE html><html lang="en"><body><script>

	var foo = 'foo';
	var myObject = { foo: 'I am myObject.foo' };

	var sayFoo = function () {
		console.log(this['foo']);
	};

	// Give myObject a sayFoo property and have it point to the sayFoo function.
	myObject.sayFoo = sayFoo;

	myObject.sayFoo(); // Logs 'I am myObject.foo'.
	sayFoo(); // Logs 'foo'.

</script></body></html>

Évidemment, la valeur de

est basée sur le contexte dans lequel la fonction est appelée. Considérez que myObject.sayFoo et sayFoo pointent tous deux vers la même fonction. Cependant, selon l'endroit où (contexte) sayFoo() est appelé, la valeur de

différera.

Si cela peut vous aider, voici le même code utilisant explicitement l'objet d'en-tête (thisarguments).


Exemple : sample101.html

<!DOCTYPE html><html lang="en"><body><script>

	window.foo = 'foo';
	window.myObject = { foo: 'I am myObject.foo' };

	window.sayFoo = function () {
		console.log(this.foo);
	};

	window.myObject.sayFoo = window.sayFoo;

	window.myObject.sayFoo();
	window.sayFoo();

</script></body></html>
thisAssurez-vous que lorsque vous transmettez une fonction ou faites plusieurs références à une fonction, vous réalisez que la valeur de celle-ci changera en fonction du contexte dans lequel vous appelez la fonction.

Toutes les variables sauf this 在一个包含在另一个函数中的函数内部使用时会发生什么。坏消息是在 ECMA 3 中,this 迷失了方向并引用了头对象(浏览器中的 window et arguments respectent la portée lexicale

func2func3 中的 this 迷失了方向,并且不是指向 myObject

Le mot clé fait référence à l'objet d'en-tête dans la fonction imbriquée

Vous vous demandez peut-être ce qui se passe lorsque

est utilisé dans une fonction contenue dans une autre fonction. La mauvaise nouvelle est que dans ECMA 3,

s'est perdu et a référencé l'objet d'en-tête (l'objet

dans le navigateur) au lieu de l'objet où la fonction est définie. foo.func1 时会发生什么。当在 foo.func1 (函数中的函数)内部调用匿名函数时,匿名函数内部的 this

Dans le code ci-dessous, les

dans func2 et func3 sont perdus et pointent non pas vers myObject mais vers l'objet principal.

Exemple : sample102.htmlthis

<!DOCTYPE html><html lang="en"><body><script>

	var myObject = {
		func1: function () {
			console.log(this); // Logs myObject.
			var func2 = function () {
				console.log(this) // Logs window, and will do so from this point on.
				var func3 = function () {
					console.log(this); // Logs window, as it’s the head object.
				} ();
			} ();
		}
	}

	myObject.func1();

</script></body></html>

La bonne nouvelle est que ce problème sera résolu dans ECMAScript 5. À présent, vous devriez être conscient de ce dilemme, surtout lorsque vous commencez à transmettre des fonctions en tant que valeurs à d'autres fonctions.

Considérez l'exemple suivant et ce qui se passe lorsque vous transmettez une fonction anonyme à foo.func1. Lorsqu'une fonction anonyme est appelée dans foo.func1 (une fonction dans une fonction), la valeur

à l'intérieur de la fonction anonyme sera une référence à l'objet principal.

this 值不会丢失,您可以简单地使用作用域链在父函数中保留对 this 的引用。以下示例演示了如何使用名为 thatExemple : sample103.html

<!DOCTYPE html><html lang="en"><body><script>

	var foo = {
		func1: function (bar) {
			bar(); // Logs window, not foo.
			console.log(this); // The this keyword here will be a reference to the foo object.
		}
	}

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

</script></body></html>

Maintenant, n'oubliez jamais : la valeur

sera toujours une référence à l'objet principal lorsque sa fonction hôte est enveloppée dans une autre fonction ou appelée dans le contexte d'une autre fonction (encore une fois, cela est corrigé dans ECMAScript 5). 🎜 🎜 🎜Utilisez la chaîne de portée pour résoudre le problème des fonctions imbriquées🎜 🎜Pour que la valeur 🎜 ne soit pas perdue, vous pouvez simplement utiliser une chaîne de portée pour conserver une référence à 🎜 dans la fonction parent. L'exemple suivant montre comment en utilisant une variable nommée that et en exploitant sa portée, nous pouvons mieux suivre le contexte de la fonction. 🎜 🎜Exemple : sample104.html🎜
<!DOCTYPE html><html lang="en"><body><script>

var myObject = {
	myProperty: 'I can see the light', 
	myMethod : function(){
		var that = this; // Store a reference to this (myObject) in myMethod scope.
		var helperFunction = function() { // Child function.
			// Logs 'I can see the light' via scope chain because that = this.
			console.log(that.myProperty); // Logs 'I can see the light'.
			console.log(this); // Logs window object, if we don't use "that".
		}();
	}
}

myObject.myMethod(); // Invoke myMethod.

</script></body></html>

使用 call()apply() 控制 this 的值

this 的值通常由调用函数的上下文确定(除非使用 new 关键字,稍后会详细介绍),但您可以使用 this 的值>apply() 或 call() 来定义调用函数时 this 指向什么对象。使用这些方法就像在说:“嘿,调用 X 函数,但告诉该函数使用 Z 对象作为 this 的值。”通过这样做,JavaScript 确定 this 值的默认方式将被覆盖。

在下一个示例中,我们创建一个对象和一个函数。然后我们通过 call() 调用该函数,以便函数内 this 的值使用 myObject 作为其上下文。 myFunction 函数内的语句将使用属性填充 myObject,而不是填充头对象。我们更改了 this (在 myFunction 内部)引用的对象。

示例:sample105.html

<!DOCTYPE html><html lang="en"><body><script>

	var myObject = {};

	var myFunction = function (param1, param2) {
		// Set via call(), 'this' points to myObject when function is invoked.
		this.foo = param1;
		this.bar = param2;
		console.log(this) // Logs Object {foo = 'foo', bar = 'bar'}
	};

	myFunction.call(myObject, 'foo', 'bar'); // Invoke function, set this value to myObject.

	console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'}

</script></body></html>

在前面的示例中,我们使用了 call(),但也可以使用 apply()。两者之间的区别在于函数参数的传递方式。使用 call(),参数只是逗号分隔的值。使用 apply(),参数值在数组内部传递,如以下示例所示。

示例:sample106.html

<!DOCTYPE html><html lang="en"><body><script>

	var myObject = {};

	var myFunction = function (param1, param2) {
		// Set via apply(), this points to myObject when function is invoked.
		this.foo = param1;
		this.bar = param2;
		console.log(this) // Logs Object {foo = 'foo', bar = 'bar'}
	};

	myFunction.apply(myObject, ['foo', 'bar']); // Invoke function, set this value.

	console.log(myObject) // Logs Object {foo = 'foo', bar = 'bar'}

</script></body></html>

这里您需要学习的是,您可以覆盖 JavaScript 在函数作用域中确定 this 值的默认方式。


在用户定义的构造函数中使用 this 关键字

当使用 new 关键字调用函数时,构造函数中声明的 this 的值指的是实例本身。换句话说:在构造函数中,我们可以在实际创建对象之前通过 this 来利用该对象。在这种情况下, this 的默认值的更改方式类似于使用 call()apply()

在下面的示例中,我们设置了一个 Person 构造函数,该函数使用 this 来引用正在创建的对象。当创建 Person 的实例时,this.name 将引用新创建的对象,并在新对象中放置一个名为 name 的属性,并将参数 (name) 中的值传递给构造函数。 p>

示例:sample107.html

<!DOCTYPE html><html lang="en"><body><script>

	var Person = function (name) {
		this.name = name || 'john doe'; // this will refer to the instance created.
	}

	var cody = new Person('Cody Lindley'); // Create an instance based on the Person constructor.

	console.log(cody.name); // Logs 'Cody Lindley'.

</script></body></html>

同样,当使用 new 关键字调用构造函数时,this 指的是“将成为的对象”。如果我们没有使用 new 关键字,则 this 的值将是调用 Person 的上下文 - 在本例中为头对象。让我们看一下以下场景:

示例:sample108.html

<!DOCTYPE html><html lang="en"><body><script>

	var Person = function (name) {
		this.name = name || 'john doe';
	}

	var cody = Person('Cody Lindley'); // Notice we did not use 'new'.

	console.log(cody.name); // Undefined. The value is actually set at window.name

	console.log(window.name); // Logs 'Cody Lindley'.

</script></body></html>

原型方法中的关键字 this 引用构造函数实例

当在添加到构造函数 prototype 属性的函数中使用时,this 指的是调用该方法的实例。假设我们有一个自定义 Person() 构造函数。作为参数,它需要人的全名。如果我们需要访问人员的全名,我们将 whatIsMyFullName 方法添加到 Person.prototype 中,以便所有 Person 实例继承该方法。当使用 this 时,该方法可以引用调用它的实例(以及它的属性)。

这里我演示了创建两个Person对象(codylisa)以及继承的whatIsMyFullName方法,其中包含this关键字来访问实例。

示例:sample109.html

<!DOCTYPE html><html lang="en"><body><script>

	var Person = function (x) {
		if (x) { this.fullName = x };
	};

	Person.prototype.whatIsMyFullName = function () {
		return this.fullName; // 'this' refers to the instance created from Person()
	}

	var cody = new Person('cody lindley');
	var lisa = new Person('lisa lindley');

	// Call the inherited whatIsMyFullName method, which uses this to refer to the instance.
	console.log(cody.whatIsMyFullName(), lisa.whatIsMyFullName());

	/* The prototype chain is still in effect, so if the instance does not have a fullName property, it will look for it in the prototype chain. Next, we add a fullName property to both the Person prototype and the Object prototype. See the notes that follow this sample. */

	Object.prototype.fullName = 'John Doe';
	var john = new Person(); // No argument is passed so fullName is not added to the instance.
	console.log(john.whatIsMyFullName()); // Logs 'John Doe'.

</script></body></html>

结论

这里要带走的概念是 that 关键字 this 用于在 prototype 对象中包含的方法内部使用时引用实例。如果实例不包含该属性,则开始查找原型。

如果 this 指向的实例或对象不包含所引用的属性,则应用适用于任何属性查找的相同规则,并且将在原型链上“查找”该属性。因此,在我们的示例中,如果 fullName 属性未包含在我们的实例中,则将在 Person.prototype.fullName 中查找 fullName 属性,然后在 Object.prototype.fullName 中查找。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn