Maison  >  Article  >  interface Web  >  Comprendre le mot-clé this en js

Comprendre le mot-clé this en js

怪我咯
怪我咯original
2017-07-07 10:35:091452parcourir

Je pense que tout le monde connaît très bien le mot-clé this. La clé this fournie en js est plus déroutante que celle du langage oo. Cet article vous présentera la compréhension de ce mot-clé en js. it

Ce mot-clé est fourni à la fois en C++ et en Java. C'est difficile lorsque vous commencez à apprendre, mais tant que vous le comprenez, il sera beaucoup plus facile à utiliser. Voici une explication détaillée de ceci. saisissez js à travers cet article pour comprendre les mots.

À ce propos, c'est une question obligatoire pour de nombreux entretiens front-end. Parfois, j'ai vu ces questions sur Internet et je les ai essayées moi-même. Eh bien, j'avais vraiment tort ! Dans le développement réel, nous rencontrerons également ce problème (bien que certaines bibliothèques de classes nous aident à le résoudre). Par exemple, lors de l'utilisation de certains frameworks, tels que : knockout, parfois nous ne comprenons pas pourquoi nous ne l'utilisons pas directement. , mais utilisez-le lorsque les paramètres sont transmis.

Ensuite, vous pouvez parler de ma compréhension de celui-ci et également l'utiliser comme note pour référence future. S'il y a quelque chose qui ne va pas, veuillez le signaler et critiquer.

1. Contrairement à C#, ceci doit pointer vers l'objet actuel.

Le point this de js est incertain, ce qui signifie qu'il peut être modifié dynamiquement. call/apply est une fonction utilisée pour changer le point pointé par ceci. Cette conception peut rendre le code plus flexible et réutilisable.

2. Cela pointe généralement vers le propriétaire de la fonction.

C'est très important ! C'est très important ! C'est très important !

C'est aussi une question d'entretien courante, le code suivant :

<script type="text/javascript">
  var number = 1;
  var obj = {
     number: 2,
    showNumber: function(){
      this.number = 3;
      (function(){          
        console.log(this.number);
      })();
      console.log(this.number);
    }
  };
  obj.showNumber();
</script>

Puisque le propriétaire de la méthode showNumber est obj, donc this.number=3 ; d'obj.

De même, le deuxième console.log imprime également le numéro d'attribut.

Pourquoi le deuxième point dit-il que cela pointe généralement vers le propriétaire de la fonction, car il y a des circonstances particulières. L'auto-exécution de fonction est un cas particulier. Dans l'auto-exécution de fonction, cela pointe vers : window. Ainsi, le premier console.log imprime le numéro d'attribut de la fenêtre.

Ajoutez donc un point :

3. Dans l'auto-exécution de la fonction, cela pointe vers l'objet window.

Extension, à ce propos, une autre chose qui prête un peu à confusion c'est que dans les événements dom, il y a généralement trois situations :

Comme suit :

1. Utilisez l'attribut label pour enregistrer l'événement. À ce stade, cela pointe vers l'objet window.

<input id="test" type="button" value="按钮" onClick="test()"/>
  function test(){alert(this)}

2. Pour 1, pour faire valoir ce point à l'entrée, vous pouvez passer ceci en paramètre.

3. Inscrivez-vous en utilisant addEventListener etc. À l’heure actuelle, cela indique également une contribution.

document.getElementById("test").addEventListener("click",test);

Dans le langage de programmation orienté objet , nous connaissons très bien le mot-clé this. Par exemple, C++, C# et Java fournissent tous ce mot-clé. Bien qu'il soit difficile au début de l'apprentissage, une fois que vous l'avez compris, il est très pratique et significatif à utiliser. JavaScript fournit également ce mot-clé, mais il est beaucoup plus « déroutant » à utiliser que dans les langages OO classiques.

Jetons un coup d'œil à ce qui prête à confusion dans les différentes façons d'utiliser cela en JavaScript ?

1. Utilisez ce mot-clé en ligne dans l'attribut d'événement de l'élément HTML :

// 可以在里面使用this  
">pision element 
 // 可以在里面使用this
 ">pision element

La méthode la plus couramment utilisée consiste à l'utiliser ici : javascipt : EventHandler(this), sous cette forme. Cependant, vous pouvez réellement écrire n'importe quelle déclaration JavaScript légale ici. Si vous le souhaitez, vous pouvez définir une classe ici (mais ce sera une classe interne). Le principe ici est que le moteur de script génère une méthode membre anonyme de l'objet instance p, et onclick pointe vers cette méthode.

2. Utilisez la méthode DOM pour utiliser le mot-clé this dans la fonction de traitement des événements  :

pision element

 var p = document.getElementById(&#39;elmtp&#39;);  
 p.attachEvent(&#39;onclick&#39;, EventHandler);  
 
 function EventHandler()  
 {  
 // 在此使用this  
 }  
  
// --> 
 
pision element

 var p = document.getElementById(&#39;elmtp&#39;);
 p.attachEvent(&#39;onclick&#39;, EventHandler);

 function EventHandler()
 {
 // 在此使用this
 }
 
// -->

À ce stade, dans le Méthode EventHandler() Le mot-clé this indique que l'objet est l'objet fenêtre d'IE. En effet, EventHandler n'est qu'une fonction ordinaire. Après attachEvent, l'appel du moteur de script n'a rien à voir avec l'objet p lui-même. En même temps, vous pouvez consulter l'attribut caller d'EventHandler, qui est égal à null. Si nous voulons obtenir la référence de l'objet p dans cette méthode, nous devons utiliser : this.event.srcElement.

3. Utilisez le mot-clé this dans la fonction de traitement d'événements en utilisant DHTML :

pision element
  
lt;mce:script language="javascript">
var p = document.getElementById(&#39;elmtp&#39;);  
p.onclick = function()  
{  
 // 在此使用this  
};  
 
/ --> 
 
pision element

 var p = document.getElementById(&#39;elmtp&#39;);
 p.onclick = function()
 {
 // 在此使用this
 };
 
// -->

Le contenu indiqué par le mot-clé this ici est l'instance d'objet de l'élément p. Utiliser DHTML dans le script pour attribuer directement une méthode EventHandler à p.onclick équivaut à ajouter une méthode membre à l'instance d'objet p. La différence entre cette méthode et la première méthode est que la première méthode utilise la méthode HTML, et voici la méthode DHTML. Le moteur d'analyse de script de cette dernière ne générera plus de méthodes anonymes.

4. Utilisez ce mot-clé dans la définition de la classe :

function JSClass()  
{  
var myName = &#39;jsclass&#39;;  
this.m_Name = &#39;JSClass&#39;;  
}  
 
JSClass.prototype.ToString = function()  
{  
alert(myName + &#39;, &#39; + this.m_Name);  
};  
 
var jc = new JSClass();  
jc.ToString(); 
 function JSClass()
 {
 var myName = &#39;jsclass&#39;;
 this.m_Name = &#39;JSClass&#39;;
 }

 JSClass.prototype.ToString = function()
 {
 alert(myName + &#39;, &#39; + this.m_Name);
 };

 var jc = new JSClass();
 jc.ToString();

  这是JavaScript模拟类定义中对this的使用,这个和其它的OO语言中的情况非常的相识。但是这里要求成员属性和方法必须使用this关键字来引用,运行上面的程序会被告知myName未定义。

5、为脚本引擎内部对象添加原形方法中的this关键字:

function.prototype.GetName = function()  
{  
var fnName = this.toString();  
fnName = fnName.substr(0, fnName.indexOf(&#39;(&#39;));  
fnName = fnName.replace(/^function/, &#39;&#39;);  
return fnName.replace(/(^\s+)|(\s+$)/g, &#39;&#39;);  
}  
function foo(){}  
alert(foo.GetName());  
 function.prototype.GetName = function()
 {
 var fnName = this.toString(); 
 fnName = fnName.substr(0, fnName.indexOf(&#39;(&#39;)); 
 fnName = fnName.replace(/^function/, &#39;&#39;); 
 return fnName.replace(/(^\s+)|(\s+$)/g, &#39;&#39;);
 }
 function foo(){}
 alert(foo.GetName());

  这里的this指代的是被添加原形的类的实例,和4中类定义有些相似,没有什么太特别的地方。

  6、结合2&4,说一个比较迷惑的this关键字使用:

view plaincopy to clipboardprint?
function JSClass()  
{  
this.m_Text = &#39;pision element&#39;;  
this.m_Element = document.createElement(&#39;p&#39;);  
this.m_Element.innerHTML = this.m_Text;  
  
this.m_Element.attachEvent(&#39;onclick&#39;, this.ToString);  
}  
  
JSClass.prototype.Render = function()  
{  
document.body.appendChild(this.m_Element);  
}   
 
JSClass.prototype.ToString = function()  
{  
alert(this.m_Text);  
};  
 
var jc = new JSClass();  
jc.Render();  
jc.ToString(); 
 function JSClass()
 {
 this.m_Text = &#39;pision element&#39;;
 this.m_Element = document.createElement(&#39;p&#39;);
 this.m_Element.innerHTML = this.m_Text;
  
 this.m_Element.attachEvent(&#39;onclick&#39;, this.ToString);
 }
  
 JSClass.prototype.Render = function()
 {
 document.body.appendChild(this.m_Element);
 } 

 JSClass.prototype.ToString = function()
 {
 alert(this.m_Text);
 };

 var jc = new JSClass();
 jc.Render(); 
 jc.ToString();

  我就说说结果,页面运行后会显示:"pision element",确定后点击文字"pision element",将会显示:"undefined"。

  7、CSS的expression表达式中使用this关键字:

height: expression(this.parentElement.height);">  
 pision element  
  
 height: expression(this.parentElement.height);">
 pision element

这里的this看作和1中的一样就可以了,它也是指代p元素对象实例本身。

  8、函数中的内部函数中使用this关键字:

view plaincopy to clipboardprint?
function OuterFoo()  
{  
this.Name = &#39;Outer Name&#39;;  
 
function InnerFoo()  
{  
var Name = &#39;Inner Name&#39;;  
alert(Name + &#39;, &#39; + this.Name);  
}  
return InnerFoo;  
}  
OuterFoo()(); 
 function OuterFoo()
 {
 this.Name = &#39;Outer Name&#39;;
 
 function InnerFoo()
 {
 var Name = &#39;Inner Name&#39;; 
 alert(Name + &#39;, &#39; + this.Name);
 }
 return InnerFoo;
 }
 OuterFoo()();

  运行结果显示是:"Inner Name, Outer Name"。按我们在2中的讲解,这里的结果如果是"Inner Name, undefined"似乎更合理些吧?但是正确的结果确实是前者,这是由于JavaScript变量作用域的问题决定的,详细了解推荐参看"原来JScript中的关键字'var'还是有文章的"一文及回复。

    归纳起来,JavaScript中的this用法有以下3种(详细用法参原文):

    1.在HTML元素事件属性 或 CSS的expression表达式 中inline方式使用this关键字——对应原文的1、7

    2.在事件处理函数中使用this关键字——对应原文的2、3

      其中可分为两种方式

      (1)DOM方式——此种方式的结果是this指向窗口(window)对象

      (2)DHTML方式——此种方式的结果是this指向p元素对象实例

    3.在类定义中使用this关键字并在其 内部函数 或 成员函数(主要是prototype产生)中使用——对应原文的4、5、8

      需要说明的是,在函数也是个对象,因此需要区分 变量定义 和 成员变量定义,如下:

view plaincopy to clipboardprint?

var variableName;    //变量定义  
//作用域:函数定义范围内  
//使用方法:直接使用variableName  
this.varName;      //成员变量定义  
//作用域:函数对象定义范围内及其成员函数中  
//使用方法:this.varName 
var variableName;    //变量定义
//作用域:函数定义范围内
//使用方法:直接使用variableName
this.varName;      //成员变量定义
//作用域:函数对象定义范围内及其成员函数中
//使用方法:this.varName

 以上归纳出的三类this的使用方法中,第一种比较容易理解,这里对原文中第6点提到的程序进行了测试和改进如下,以说明上述后两种使用方法:

view plaincopy to clipboardprint?

    function JSClass()  
    {  
      var varText = "func variable!";                 //函数中的普通变量  
      this.m_Text = &#39;func member!&#39;;                    //函数类的成员变量  
      this.m_Element = document.createElement(&#39;p&#39;);   //成员变量,创建一个p对象  
      this.m_Element.innerHTML = varText;             //使用函数的普通变量  
      this.m_Element.attachEvent(&#39;onclick&#39;, this.ToString);  //给这个对象的事件连上处理函数  
      this.newElement = document.createElement(&#39;p&#39;);  
      this.newElement.innerHTML = "new element";   
      this.newElement.m_Text = "new element text!";      //给创建的对象建个成员  
      this.newElement.onclick = function()  
      {  
        alert(this.m_Text);                       //指向p对象的成员  
      };  
    }  
   
    JSClass.prototype.Render = function()  
    {  
      document.body.appendChild(this.m_Element);       //把p对象挂在窗口上  
      document.body.appendChild(this.newElement);  
    }    
 
    JSClass.prototype.ToString = function()  
    {  
      alert(this.m_Text);                         //指向窗口(window)对象  
    };  
 
    function initialize(){  
      var jc = new JSClass();  
      jc.Render();  
      jc.ToString();                             //里面的this指向JSClass类的实例,里面有m_Text成员  
    }  
    
// -->  

    initialize();  
    
// -->  
  
 function JSClass()
  {
   var varText = "func variable!";     //函数中的普通变量
    this.m_Text = &#39;func member!&#39;;     //函数类的成员变量
    this.m_Element = document.createElement(&#39;p&#39;); //成员变量,创建一个p对象
    this.m_Element.innerHTML = varText;    //使用函数的普通变量
    this.m_Element.attachEvent(&#39;onclick&#39;, this.ToString); //给这个对象的事件连上处理函数
    this.newElement = document.createElement(&#39;p&#39;);
    this.newElement.innerHTML = "new element"; 
    this.newElement.m_Text = "new element text!";  //给创建的对象建个成员
    this.newElement.onclick = function()
   {
     alert(this.m_Text);      //指向p对象的成员
   };
  }
  
  JSClass.prototype.Render = function()
  {
    document.body.appendChild(this.m_Element);  //把p对象挂在窗口上
    document.body.appendChild(this.newElement);
  }   

  JSClass.prototype.ToString = function()
  {
    alert(this.m_Text);       //指向窗口(window)对象
  };

 function initialize(){
   var jc = new JSClass();
   jc.Render(); 
   jc.ToString();        //里面的this指向JSClass类的实例,里面有m_Text成员
  }
  
// -->

   initialize();
  
// -->

上面的代码执行结果是:

页面加载时,弹出对话框,输出func member!

页面上显示

 func variable!
 new element

单击func variable时,弹出对话框,显示undefined

  ——因为这时toString函数里的this指针指向window

单击new element时,弹出对话框显示new element text!

  ——因为这时toString函数里的this指针指向p元素,而该元素已经定义了m_Text成员(this.newElement.m_Text = "new element text!")

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