Rumah  >  Artikel  >  hujung hadapan web  >  Meneroka perkara yang ditunjukkan oleh penunjuk ini dalam pengetahuan JavaScript_Basic

Meneroka perkara yang ditunjukkan oleh penunjuk ini dalam pengetahuan JavaScript_Basic

WBOY
WBOYasal
2016-05-16 15:04:201160semak imbas

Explorez vers quoi ce pointeur pointe en JavaScript

Tout d'abord, il faut dire que le but de ceci ne peut pas être déterminé lorsque la fonction est définie. Ce n'est que lorsque la fonction est exécutée que l'on peut déterminer à qui cela pointe. l'a appelé (ceci Il y a quelques problèmes avec cette phrase, et j'expliquerai pourquoi il y a un problème plus tard. Bien que la plupart des articles sur Internet le disent, même si dans de nombreux cas, il n'y aura aucun problème à la comprendre de cette façon, en fait, il est inexact de le comprendre de cette façon, donc il y aura un sentiment d'incertitude lorsque vous comprendrez cela), j'explorerai ensuite cette question en profondeur.

Pourquoi devriez-vous apprendre cela ? Si vous avez étudié la programmation fonctionnelle ou la programmation orientée objet, alors vous savez certainement à quoi elle sert. Si vous ne l'avez pas étudié, vous n'avez pas besoin de lire cet article pour le moment, vous pouvez également le lire. si cela vous intéresse. Après tout, c'est js. Quelque chose qui doit être maîtrisé.

Exemple 1 :

function a(){
  var user = "追梦子";
  console.log(this.user); //undefined
  console.log(this); //Window
}
a();

D'après ce que nous avons dit ci-dessus, cela pointe finalement vers l'objet qui l'appelle. La fonction a ici est en fait pointée par l'objet Window, comme peut le prouver le code suivant.

function a(){
  var user = "追梦子";
  console.log(this.user); //undefined
  console.log(this);  //Window
}
window.a();

C'est la même chose que le code ci-dessus. En fait, alert est également un attribut de window et est également cliqué par window.

Exemple 2 :

var o = {
  user:"追梦子",
  fn:function(){
    console.log(this.user); //追梦子
  }
}
o.fn();

Ceci pointe ici vers l'objet o, car lorsque vous appelez ce fn, il est exécuté via o.fn(), donc le point naturel est l'objet o. Permettez-moi de souligner à nouveau que le point de ceci ne peut pas être déterminé quand. la fonction est créée. Oui, cela peut être décidé au moment de l'appel. Celui qui appelle désigne qui.

En fait, l'exemple 1 et l'exemple 2 ne sont pas assez précis. L'exemple suivant peut renverser la théorie ci-dessus.

Si vous voulez bien comprendre cela, vous devez lire les exemples suivants

Exemple 3 :

var o = { user:"追梦子", 
fn:function()
{ console.log(this.user); //追梦子 } } 
window.o.fn();

Ce code est presque le même que le code ci-dessus, mais pourquoi cela ne pointe-t-il pas ici vers window Si selon la théorie ci-dessus, cela pointe finalement vers l'objet qui l'appelle. Voici un aparté, window C'est un. objet global dans js. La variable que nous créons ajoute en fait des attributs à la fenêtre, nous pouvons donc utiliser le point fenêtre ou l'objet ici.

N'expliquons pas pourquoi ce code dans le code ci-dessus ne pointe pas vers la fenêtre. Regardons un morceau de code.

var o = {
  a:10,
  b:{
    a:12,
    fn:function(){
      console.log(this.a); //12
    }
  }
}
o.b.fn();

L'objet o est également signalé ici, mais cela ne l'exécute pas non plus. Alors vous direz certainement que ce que j'ai dit au début est faux ? En fait, ce n'est pas le cas, c'est juste que ce que j'ai dit au début était inexact. Ensuite, j'ajouterai une phrase, je pense que vous pouvez parfaitement comprendre le problème soulevé par cela.

Cas 1 : S'il y a this dans une fonction, mais qu'elle n'est pas appelée par l'objet de niveau supérieur, alors cela pointe vers window. Ce qu'il faut noter ici, c'est que dans la version stricte de js, ce n'est pas le cas. pointez vers la fenêtre, mais nous ne discuterons pas ici de la version stricte. Si vous souhaitez en savoir plus, vous pouvez effectuer une recherche en ligne.

Cas 2 : S'il y a this dans une fonction et que cette fonction est appelée par l'objet de niveau supérieur, alors cela pointe vers l'objet de niveau supérieur.

Cas 3 : S'il y a ceci dans une fonction qui contient plusieurs objets, même si la fonction est appelée par l'objet le plus externe, cela ne pointe que vers l'objet au-dessus d'elle, si vous n'y croyez pas. puis continuons à examiner quelques exemples.

var o = {
  a:10,
  b:{
    // a:12,
    fn:function(){
      console.log(this.a); //undefined
    }
  }
}
o.b.fn();

Bien qu'il n'y ait pas d'attribut a dans l'objet b, cela pointe également vers l'objet b, car cela ne pointera que vers son objet de niveau supérieur, qu'il y ait ou non quelque chose que cela veuille dans cet objet.

Il existe également une situation plus particulière, Exemple 4 :

var o = {
  a:10,
  b:{
    a:12,
    fn:function(){
      console.log(this.a); //undefined
      console.log(this); //window
    }
  }
}
var j = o.b.fn;
j();

Ceci pointe vers la fenêtre. Êtes-vous confus ? En fait, c’est parce que vous n’avez pas compris une phrase, ce qui est également crucial.

Cela pointe toujours vers l'objet qui l'a appelé en dernier, c'est-à-dire qui l'a appelé lors de son exécution. Dans l'exemple 4, bien que la fonction fn soit référencée par l'objet b, elle n'est pas affectée lorsque fn est affectée à la variable j. Il n'est pas exécuté, donc il pointe finalement vers window. Ceci est différent de l'exemple 3, qui exécute directement fn.

C'est en fait la même chose, mais cela indiquera quelque chose de différent dans différentes situations. Il y a quelques petites erreurs dans le résumé ci-dessus, qui ne peuvent pas être considérées comme des erreurs, mais dans différents environnements, la situation sera différente ensuite. le temps, donc je ne peux pas l'expliquer clairement d'un seul coup, je ne peux que vous laisser en faire l'expérience lentement.

Version constructeur de ceci :

function Fn(){
  this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子

这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象Fn中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

除了上面的这些以外,我们还可以自行改变this的指向,关于自行改变this的指向请看JavaScript中call,apply,bind方法的总结这篇文章,详细的说明了我们如何手动更改this的指向。

更新一个小问题当this碰到return时

function fn() 
{ 
  this.user = '追梦子'; 
  return {}; 
}
var a = new fn; 
console.log(a.user); //undefined

再看一个

function fn() 
{ 
  this.user = '追梦子'; 
  return function(){};
}
var a = new fn; 
console.log(a.user); //undefined

再来

function fn() 
{ 
  this.user = '追梦子'; 
  return 1;
}
var a = new fn; 
console.log(a.user); //追梦子
function fn() 
{ 
  this.user = '追梦子'; 
  return undefined;
}
var a = new fn; 
console.log(a.user); //追梦子

什么意思呢?

如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

function fn() 
{ 
  this.user = '追梦子'; 
  return undefined;
}
var a = new fn; 
console.log(a); //fn {user: "追梦子"}

还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。

function fn() 
{ 
  this.user = '追梦子'; 
  return null;
}
var a = new fn; 
console.log(a.user); //追梦子

知识点补充:

1.在严格版中的默认的this不再是window,而是undefined。

2.new操作符会改变函数this的指向问题,虽然我们上面讲解过了,但是并没有深入的讨论这个问题,网上也很少说,所以在这里有必要说一下。

function fn(){
  this.num = 1;
}
var a = new fn();
console.log(a.num); //1

为什么this会指向a?首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn