Ceci en JavaScript est relativement flexible. Cela peut être différent selon différents environnements ou lorsque la même fonction est appelée de différentes manières. Mais il y a un principe général, c'est-à-dire que ceci fait référence à l'objet qui appelle la fonction.
Une introduction approfondie à la fermeture de JavaScript (Closure)
Une entrée -introduction approfondie à JavaScript
Une introduction approfondie à la chaîne de prototypes et à l'héritage de JavaScript
Voici mes notes d'étude, qui sont répertoriés en 8 situations.
Ceci dans la portée globale pointe généralement vers l'objet global, qui est la fenêtre dans le nœud du navigateur. , cet objet est global.
console.log(this.document === document); // true (document === window.document) console.log(this === window); // true this.a = 37; //相当于创建了一个全局变量a console.log(window.a); // 37
Déclaration de fonction générale ou expression de fonction Si la fonction est appelée directement, this pointe toujours vers l'objet global, this. l'objet est une fenêtre, cet objet est global dans le nœud.
function f1(){ return this; } f1() === window; // true, global object
Donnez un autre exemple, ce sera très clair après l'avoir lu
function test(){ this.x = 1; alert(this.x); } test(); // 1
Afin de prouver qu'il s'agit de l'objet global, apportez quelques modifications au code :
var x = 1; function test(){ alert(this.x); } test(); // 1
Le résultat courant est toujours 1. Modifiez-le à nouveau :
var x = 1; function test(){ this.x = 0; } test(); alert(x); //0
Mais en mode strict, lorsqu'une fonction est appelée, cela pointe vers undefined. C'est l'une des raisons pour lesquelles le nœud utilise le mode strict.
function f2(){ "use strict"; // see strict mode return this; } f2() === undefined; // true
Il est courant de l'utiliser comme méthode objet.
Dans l'exemple suivant, nous créons un objet littéral o. Il y a un attribut f dans o. Sa valeur est un objet fonction. Nous appelons souvent la fonction comme la valeur de l'attribut objet. Lorsqu'il est appelé comme méthode d'un objet, cela pointe vers l'objet o
var o = { prop: 37, f: function() { return this.prop; } }; console.log(o.f()); // logs 37
Nous ne devons pas nécessairement définir un objet comme une fonction littérale. Dans le cas suivant, nous définissons uniquement un objet o. , si la fonction indépendante() est appelée directement, cela pointera vers window, mais lorsque nous créons temporairement une propriété f via affectation et la pointons vers l'objet fonction, nous obtenons toujours 37.
var o = {prop: 37}; function independent() { return this.prop; } o.f = independent; console.log(o.f()); // logs 37
Cela ne dépend donc pas de la façon dont la fonction est créée, mais tant que la fonction est appelée comme méthode de l'objet, cela pointera vers l'objet.
Dans l'exemple suivant : on crée d'abord un objet o, qui a un attribut f et une fonction En tant que valeur de l'attribut d'objet, nous créons un objet p via Object.create(o), p est un objet vide, et son prototype pointera vers o, puis utilisera p.a = 1 pour créer les attributs sur ; l'objet p, alors Quand on appelle la méthode sur le prototype, this.a, this.b peut toujours obtenir a et b sur l'objet p. Ce qu'il faut noter ici, c'est que le prototype de p est o. Lorsque nous appelons p.f(), nous appelons l'attribut f sur la chaîne prototype o Celui-ci sur la chaîne prototype peut obtenir l'objet actuel p.
var o = {f:function(){ return this.a + this.b; }}; var p = Object.create(o); p.a = 1; p.b = 4; console.log(p.f()); // 5
this dans la méthode get/set pointera généralement vers l'objet où se trouve la méthode get/set
function modulus(){ return Math.sqrt(this.re * this.re + this.im * this.im); } var o = { re: 1, im: -1, get phase(){ return Math.atan2(this.im, this.re); } }; Object.defineProperty(o, 'modulus', { //临时动态给o对象创建modules属性 get: modulus, enumerable:true, configurable:true}); console.log(o.phase, o.modulus); // logs -0.78 1.4142
dans le constructeur utilise new pour appeler MyClass en tant que constructeur, cela pointera vers un objet vide, et le prototype de cet objet pointera vers MyClass.prototype (voir cet article pour un résumé de la chaîne de prototypes), mais l'affectation de this.a = 37 a été faite lors de l'appel, donc à la fin cela sera utilisé comme valeur de retour (aucune instruction return n'est écrite, ou si le return est un type de base, ce sera être utilisé comme valeur de retour), le deuxième exemple d'instruction return Si l'objet est retourné, a = 38 sera utilisé comme valeur de retour
function MyClass(){ this.a = 37; } var o = new MyClass(); console.log(o.a); // 37 function C2(){ this.a = 37; return {a : 38}; } o = new C2(); console.log(o.a); // 38
En plus des différentes méthodes d'appel, certaines méthodes d'objets fonction peuvent modifier l'exécution de la fonction, comme call/apply.
Il n'y a fondamentalement aucune différence entre call et apply, sauf que call transmet les paramètres de manière plate, tandis que apply transmet un tableau. Prenons l'exemple ci-dessous
Quand devez-vous utiliser l'appel et postuler ? Par exemple, si nous voulons appeler Object.prototype.toString, mais que nous voulons spécifier un certain this, alors nous pouvons utiliser Object.prototype.toString.call(this) pour appeler certaines méthodes qui ne peuvent pas être appelées directement. Prenons l'exemple suivant :
function add(c, d){ return this.a + this.b + c + d; } var o = {a:1, b:3}; add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 //第一个参数接收的是你想作为this的对象 add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 function bar() { console.log(Object.prototype.toString.call(this)); } bar.call(7); // "[object Number]"
méthode de liaison est fournie à partir d'es5, donc ie9 ne prend en charge que
function f(){ return this.a; } var g = f.bind({a : "test"}); //想把某个对象作为this的时候,就把它传进去,得到一个新对象g console.log(g()); // test //重复调用的时候,this已经指向bind参数。这对于我们绑定一次需要重复调用依然实现绑定的话,会比apply和call更加高效(看下面这个例子) var o = {a : 37, f : f, g : g}; console.log(o.f(), o.g()); // 37, test //o.f()通过对象的属性调用,this指向对象o;比较特殊的是即使我们把新绑定的方法作为对象的属性调用,o.g()依然会按之前的绑定去走,所以答案是test不是g
Quand je travaillais sur le projet, j'ai réalisé à quel point ces concepts de base sont importants. Si vous ne les mettez pas en œuvre un par un, vous tomberez vraiment dans un piège accidentellement. À l'avenir, je résumerai également la chaîne de prototypes, la portée, l'héritage, l'appel de chaîne, la régularité et d'autres connaissances. Bienvenue à suivre
Ce qui précède est l'explication détaillée de ceci en JavaScript. Pour plus de contenu connexe, veuillez. faites attention à PHP Chinese Net (www.php.cn) !