Maison  >  Article  >  interface Web  >  Une compréhension approfondie de ce vers quoi ce pointeur pointe en JavaScript

Une compréhension approfondie de ce vers quoi ce pointeur pointe en JavaScript

黄舟
黄舟original
2017-02-23 13:46:52973parcourir

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'appelle (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 signalée par l'objet Window Ce qui suit. code Cela peut être prouvé.

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

C'est le même 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, parce que vous appelez ce fn via o.fn(), alors le point naturel est l'objet o, ici Permettez-moi de souligner encore une fois que le point de ceci ne peut pas être déterminé lorsque la fonction est créée. Il ne peut être déterminé que lorsqu'elle est appelée, assurez-vous de comprendre cela.

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. pareil, mais pourquoi cela ne pointe-t-il pas ici window ? Si nous suivons la théorie ci-dessus, cela pointe finalement vers l'objet qui l'appelle. Voici un aparté, window est un objet global en js, et la variable que nous créons est en fait. Ajoutez des attributs à la fenêtre afin de pouvoir utiliser le point de fenêtre ou l'objet ici.

N'expliquons pas pourquoi ceci 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, cela pointe vers autre chose que window. mais nous ne discuterons pas de la version stricte ici. Si vous voulez 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 this dans une fonction, cette fonction contient plusieurs objets. Bien que cette fonction soit appelée par l'objet le plus externe, cela ne pointe que vers l'objet au-dessus d'elle. n'y croyez pas, alors continuons à regarder quelques exemples.

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

Même s'il n'y a 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. objet.

Il existe un autre cas particulier, 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();

Ici, cela 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, lorsque fn est affecté à la variable j, ce n'est pas le cas. 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 différents points 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 la situation sera différente selon différentes situations. circonstances, donc je ne peux pas tout expliquer d'un coup, je ne peux que vous laisser l'expérimenter 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就会被这个空的对象替代。

 以上就是JavaScript中this指针指向的彻底理解的内容,更多相关内容请关注PHP中文网(www.php.cn)! 


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