Heim  >  Artikel  >  Web-Frontend  >  Das Schlüsselwort this in js verstehen

Das Schlüsselwort this in js verstehen

怪我咯
怪我咯Original
2017-07-07 10:35:091397Durchsuche

Ich glaube, dass jeder mit dem Schlüsselwort „this“ in js sehr vertraut ist. Dieser Artikel wird Ihnen das Verständnis dieses Schlüsselworts in „js“ näherbringen it

Dieses Schlüsselwort wird sowohl in C++ als auch in Java bereitgestellt. Es ist zunächst schwierig, es zu lernen, aber sobald Sie es verstanden haben, wird es viel einfacher sein, es zu verwenden. Hier finden Sie eine detaillierte Erklärung dieses Schlüssels js durch diesen Artikel Wortverständnis.

Diesbezüglich ist es eine Pflichtfrage für viele Front-End-Interviews. Manchmal habe ich diese Fragen im Internet gesehen und es selbst versucht. In der tatsächlichen Entwicklung werden wir auch auf dieses Problem stoßen (obwohl uns einige Klassenbibliotheken dabei helfen, damit umzugehen). Wenn wir beispielsweise einige Frameworks wie Knockout verwenden, verstehen wir manchmal nicht, warum wir dies nicht direkt verwenden , aber verwenden Sie dies als Parameter, die übergeben werden.

Als nächstes können Sie über mein Verständnis davon sprechen und es auch als Notiz für zukünftige Referenzzwecke verwenden. Wenn etwas nicht stimmt, weisen Sie es bitte darauf hin und kritisieren Sie es.

1. Im Gegensatz zu C# muss dies auf das aktuelle Objekt verweisen.

Dieser Punkt von js ist unsicher, was bedeutet, dass er dynamisch geändert werden kann. call/apply ist eine Funktion, die verwendet wird, um den hierdurch angezeigten Punkt zu ändern. Dieses Design kann den Code flexibler und wiederverwendbar machen.

2. Dies weist im Allgemeinen auf den Eigentümer der Funktion hin.

Das ist sehr wichtig! Das ist sehr wichtig! Das ist sehr wichtig!

Dies ist auch eine häufige Interviewfrage, der folgende Code:

<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>

Da der Besitzer der showNumber-Methode obj ist, zeigt this.number=3; dies auf das Attribut number von obj .

Ebenso gibt das zweite console.log auch die Attributnummer aus.

Warum heißt es im zweiten Punkt, dass dies im Allgemeinen auf den Eigentümer der Funktion hinweist, da es besondere Umstände gibt? Die Selbstausführung einer Funktion ist ein Sonderfall. Bei der Selbstausführung einer Funktion verweist dies auf: window. Das erste console.log gibt also die Attributnummer des Fensters aus.

Fügen Sie also einen Punkt hinzu:

3. Bei der Selbstausführung der Funktion zeigt dies auf das Fensterobjekt.

Erweiterung, was diesbezüglich etwas verwirrend ist, ist, dass es bei Dom-Events normalerweise drei Situationen gibt:

Wie folgt:

1. Verwenden Sie das Label-Attribut, um das Ereignis zu registrieren. Dies zeigt auf das Fensterobjekt.

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

2. Um diesen Punkt auf die Eingabe hinzuweisen, können Sie dies als Parameter übergeben.

3. Registrieren Sie sich mit addEventListener usw. Zu diesem Zeitpunkt deutet dies auch auf eine Eingabe hin.

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

In der objektorientierten Programmiersprache sind wir mit dem Schlüsselwort this sehr vertraut. Beispielsweise bieten C++, C# und Java dieses Schlüsselwort. Obwohl es zu Beginn des Lernens schwierig ist, ist es sehr praktisch und sinnvoll, es zu verwenden, sobald man es verstanden hat. Auch JavaScript stellt dieses Schlüsselwort zur Verfügung, die Verwendung ist jedoch viel „verwirrender“ als in klassischen OO-Sprachen.

Werfen wir einen Blick darauf, was an den verschiedenen Verwendungsmöglichkeiten in JavaScript verwirrend ist.

1. Verwenden Sie dieses Schlüsselwort inline im Ereignisattribut des HTML-Elements:

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

Die am häufigsten verwendete Methode ist die Verwendung hier: javascirpt: EventHandler(this), in dieser Form. Allerdings können Sie hier tatsächlich jede beliebige JavaScript-Anweisung schreiben. Wenn Sie möchten, können Sie hier eine Klasse definieren (es wird jedoch eine innere Klasse sein). Das Prinzip hierbei besteht darin, dass die Skript-Engine eine anonyme Mitgliedsmethode des p-Instanzobjekts generiert und onclick auf diese Methode verweist.

2. Verwenden Sie die DOM-Methode, um das Schlüsselwort this in der Funktion Ereignisverarbeitung zu verwenden:

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
 }
 
// -->

Zu diesem Zeitpunkt in der EventHandler()-Methode Das Schlüsselwort this gibt an, dass das Objekt das Fensterobjekt des IE ist. Dies liegt daran, dass EventHandler nur eine gewöhnliche Funktion ist. Nach attachmentEvent hat der Aufruf der Skript-Engine nichts mit dem p-Objekt selbst zu tun. Gleichzeitig können Sie sich das Caller-Attribut von EventHandler ansehen, das gleich null ist. Wenn wir in dieser Methode die p-Objektreferenz erhalten möchten, sollten wir Folgendes verwenden: this.event.srcElement.

3. Verwenden Sie das Schlüsselwort this in der Ereignisverarbeitungsfunktion mit 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
 };
 
// -->

Der durch das Schlüsselwort this hier angegebene Inhalt ist die Objektinstanz des p-Elements. Die Verwendung von DHTML im Skript zum direkten Zuweisen einer EventHandler-Methode zu p.onclick entspricht dem Hinzufügen einer Mitgliedsmethode zur p-Objektinstanz. Der Unterschied zwischen dieser Methode und der ersten Methode besteht darin, dass die erste Methode die HTML-Methode verwendet und hier die DHTML-Methode verwendet. Die Skript-Parsing-Engine in letzterer generiert keine anonymen Methoden mehr.

4. Verwenden Sie dieses Schlüsselwort in der Klassendefinition:

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!")

Das obige ist der detaillierte Inhalt vonDas Schlüsselwort this in js verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn