Maison > interface Web > js tutoriel > le corps du texte

Partager des exemples de ceci, appliquer, appeler et lier dans JS

小云云
Libérer: 2018-02-08 11:10:27
original
1363 Les gens l'ont consulté

Ceci pointe vers

Dans ES5, en fait, le but de ceci adhère toujours à un principe : cela pointe toujours vers le dernier objet qui l'a appelé Allez, lis-le trois fois après moi : ceci. pointe toujours vers le dernier objet qui l'a appelé. Cet objet, ceci pointe toujours vers le dernier objet qui l'a appelé, cela pointe toujours vers le dernier objet qui l'a appelé. Souvenez-vous de cette phrase, vous en connaissez déjà la moitié.

C'est une autre question d'entretien classique. Ceci, postuler, appeler et lier en JS est une question d'entretien classique. Il est préférable de comprendre la différence entre la direction de ceci et appeler, postuler et lier. Suivons l'éditeur de Script House pour en apprendre davantage, postuler, appeler et lier.

Jetons un coup d'œil à l'exemple le plus simple :

Exemple 1 :

 var name = "windowsName";
 function a() {
  var name = "Cherry";
  console.log(this.name);   // windowsName
  console.log("inner:" + this); // inner: Window
 }
 a();
 console.log("outer:" + this)   // outer: Window
Copier après la connexion

Je crois que tout le monde sait pourquoi le journal est windowsName, car d'après ce qui précède, comme le en disant "cela pointe toujours vers le dernier objet qui l'a appelé", regardons le dernier endroit où a a été appelé, a();, l'objet qui n'a pas été appelé auparavant est l'objet global window, qui est équivalent à window.a (); notez qu'ici nous n'utilisons pas le mode strict. Si le mode strict est utilisé, l'objet global n'est pas défini et l'erreur Uncaught TypeError : Impossible de lire la propriété 'nom' de non défini sera signalée.

Regardez à nouveau cet exemple :

Exemple 2 :

var name = "windowsName";
 var a = {
  name: "Cherry",
  fn : function () {
   console.log(this.name);  // Cherry
  }
 }
 a.fn();
Copier après la connexion

Dans cet exemple, la fonction fn est appelée par l'objet a, donc la valeur imprimée est dans un valeur du nom. Est-ce un peu plus clair~

Faisons un petit changement :

Exemple 3 :

var name = "windowsName";
 var a = {
  name: "Cherry",
  fn : function () {
   console.log(this.name);  // Cherry
  }
 }
 window.a.fn();
Copier après la connexion

La raison pour laquelle Cherry est imprimé ici est aussi à cause de la phrase juste Maintenant, comme le dit le proverbe, "cela pointe toujours vers l'objet qui l'a appelé en dernier", le dernier objet qui l'a appelé est toujours l'objet a.

Reprenons cet exemple :

Exemple 4 :

 var name = "windowsName";
 var a = {
  // name: "Cherry",
  fn : function () {
   console.log(this.name);  // undefined
  }
 }
 window.a.fn();
Copier après la connexion

Pourquoi undéfini est-il imprimé ici ? En effet, comme nous venons de le décrire, fn est appelé par l'objet a, ce qui signifie que le this interne de fn est l'objet a et que name n'est pas défini dans l'objet a, donc la valeur de this.name dans log n'est pas définie.

Cet exemple illustre encore : cela pointe toujours vers l'objet qui l'a appelé en dernier, car l'objet qui a appelé fn en dernier était a, donc même s'il n'y a pas d'attribut name dans a, il ne continuera pas à rechercher ceci à partir du nom de l'objet précédent, mais sortie directement indéfinie.

Regardons un exemple plus délicat :

Exemple 5 :

 var name = "windowsName";
 var a = {
  name : null,
  // name: "Cherry",
  fn : function () {
   console.log(this.name);  // windowsName
  }
 }
 var f = a.fn;
 f();
Copier après la connexion

Vous avez peut-être des questions ici, pourquoi n'est-ce pas Cherry ? C'est parce que bien que ce soit un objet ? La méthode fn est affectée à la variable f, mais elle n'est pas appelée. Alors lisez-moi cette phrase : "cela pointe toujours vers l'objet qui l'a appelé en dernier." Puisque f n'a pas été appelé tout à l'heure, fn() est toujours appelé. à la fin, la fenêtre s'appelle. Cela pointe donc vers la fenêtre.

Nous pouvons voir à partir des cinq exemples ci-dessus que l'intérêt de ceci ne peut pas être déterminé lors de sa création. Dans es5, cela pointe toujours vers l'objet qui l'a appelé en dernier.

Regardons un autre exemple :

Exemple 6 :

 var name = "windowsName";
 function fn() {
  var name = 'Cherry';
  innerFunction();
  function innerFunction() {
   console.log(this.name);  // windowsName
  }
 }
 fn()
Copier après la connexion

Vous devriez être capable de comprendre pourquoi cela se produit après l'avoir lu maintenant (o゚▽゚) o.

Comment changer le point de ceci

J'ai résumé les méthodes suivantes pour changer le point de ceci :

Utilisez la fonction flèche ES6

Utilisez-la à l'intérieur de la fonction _this = this

Utilisez apply, call, bind

new pour instancier un objet

Exemple 7 :

var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   },100);
  }
 };
 a.func2()  // this.func1 is not a function
Copier après la connexion

sans utiliser de flèche fonctions Dans ce cas, une erreur sera signalée car le dernier objet à appeler setTimeout est window, mais il n'y a pas de fonction func1 dans window.

Nous allons transformer cet exemple en démo dans cette section de modification de ce pointeur.

Fonction flèche

Comme nous le savons tous, la fonction flèche d'ES6 peut éviter les pièges liés à son utilisation dans ES5. Le this d'une fonction fléchée pointe toujours vers ceci lorsque la fonction est définie, pas lorsqu'elle est exécutée. , la fonction flèche doit se souvenir de cette phrase : "Il n'y a pas de liaison this dans la fonction flèche, et sa valeur doit être déterminée en recherchant la chaîne de portée. Si la fonction flèche est incluse par une fonction non-flèche, cette liaison est la fonction non-flèche la plus proche est this, sinon, ceci n'est pas défini".

Exemple 8 :

 var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   setTimeout( () => {
    this.func1()
   },100);
  }
 };
 a.func2()  // Cherry
Copier après la connexion

Utilisez _this = this à l'intérieur de la fonction

Si vous n'utilisez pas ES6, alors cette méthode devrait être la plus simple et sans erreur. De cette manière, nous enregistrons d'abord l'objet qui appelle cette fonction dans la variable _this, puis utilisons ce _this dans la fonction, afin que _this ne change pas.

Exemple 9 :

 var name = "windowsName";
 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)  
  },
  func2: function () {
   var _this = this;
   setTimeout( function() {
    _this.func1()
   },100);
  }
 };
 a.func2()  // Cherry
Copier après la connexion

Dans cet exemple, dans func2, définissez d'abord var _this = this;, où c'est l'objet a qui appelle func2, afin d'éviter que SetTimeout soit appelé par fenêtre, ce qui fait que cela dans setTimeout est une fenêtre. Nous attribuons this (pointant vers la variable a) à une variable _this, de sorte que lorsque nous utilisons _this dans func2, elle pointe vers l'objet a.

Utiliser apply, call et bind

L'utilisation des fonctions apply, call et bind peut également changer la direction de cela. Le principe sera discuté plus tard. Voyons d'abord comment. il est implémenté :

Utilisez apply

Exemple 10 :

 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.apply(a),100);
  }
 };
 a.func2()   // Cherry
Copier après la connexion

Utilisez call

Exemple 11 :

 var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.call(a),100);
  }
 };
 a.func2()   // Cherry
Copier après la connexion

Utilisez bind

Exemple 12 :

var a = {
  name : "Cherry",
  func1: function () {
   console.log(this.name)
  },
  func2: function () {
   setTimeout( function () {
    this.func1()
   }.bind(a)(),100);
  }
 };
 a.func2()   // Cherry
Copier après la connexion

Différences entre apply, call et bind

刚刚我们已经介绍了 apply、call、bind 都是可以改变 this 的指向的,但是这三个函数稍有不同。

在 MDN 中定义 apply 如下;

apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数

语法:

fun.apply(thisArg, [argsArray])
Copier après la connexion

thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。

argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。

apply 和 call 的区别

其实 apply 和 call 基本类似,他们的区别只是传入的参数不同。

call 的语法为:

fun.call(thisArg[, arg1[, arg2[, ...]]])
Copier après la connexion

所以 apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。

例 13:

var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.apply(a,[1,2])  // 3
Copier après la connexion

例 14:

var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.call(a,1,2)  // 3
Copier après la connexion

bind 和 apply、call 区别

我们先来将刚刚的例子使用 bind 试一下

 var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.bind(a,1,2)
Copier après la connexion

我们会发现并没有输出,这是为什么呢,我们来看一下 MDN 上的文档说明:

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

所以我们可以看出,bind 是创建一个新的函数,我们必须要手动去调用:

var a ={
  name : "Cherry",
  fn : function (a,b) {
   console.log( a + b)
  }
 }
 var b = a.fn;
 b.bind(a,1,2)()   // 3
Copier après la connexion

相关推荐:

html的标签中的this应该如何使用

js中this对象用法实例详解

js中this的理解

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal