Home > Web Front-end > JS Tutorial > Understanding the this keyword in js

Understanding the this keyword in js

怪我咯
Release: 2017-07-07 10:35:09
Original
1498 people have browsed it

I believe everyone is very familiar with this keyword. The key to this provided in js is more confusing than that in oo language. This article will introduce to you the understanding of this keyword in js. Friends who need it can refer to it

this keyword is provided in both C++ and Java. It is difficult when you first start learning, but once you understand it, it will be much easier to use. Here is a detailed explanation of the this key in js through this article. word understanding.

About this, it is a required question for many front-end interviews. Sometimes I see these questions on the Internet and try it myself. Well, I am really wrong! In actual development, we will also encounter this problem (although some class libraries will help us deal with it). For example, when using some frameworks, such as: knockout, sometimes we don’t understand why we don’t use this directly, but use this as Parameters are passed in.

Next, you talk about my understanding of it, and also as a note for future reference. If there is anything wrong, please point out and criticize.

1. Unlike C#, this must point to the current object.

The this pointer of js is uncertain, which means it can be changed dynamically. call/apply is a function used to change the point pointed by this. This design can make the code more flexible and reusable.

2. This generally points to the owner of the function.

this point is very important! this point is very important! this point is very important!

This is also a common interview question, as shown in the following 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>
Copy after login

Since the owner of the showNumber method is obj, this.number=3; this points to the attribute number of obj.

Similarly, the second console.log also prints the attribute number.

Why does the second point say that generally this points to the owner of the function, because there are special circumstances. Function self-execution is a special case. In function self-execution, this points to: window. So the first console.log prints the attribute number of window.

So we need to add something:

3. In function self-execution, this points to the window object.

Extension, regarding this, another thing that is a bit confusing is that in dom events, there are usually three situations:

As follows:

1. Use the label attribute to register the event. At this time, this points to the window object.

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

2. For 1, to make this point to the input, you can pass this as a parameter.

3. Use addEventListener to register. At this time this also points to input.

document.getElementById("test").addEventListener("click",test);
Copy after login

In object-orientedprogramming language, we are very familiar with the this keyword. For example, C++, C# and Java all provide this keyword. Although it is difficult at the beginning of learning, once you understand it, it is very convenient and meaningful to use. JavaScript also provides this keyword, but its use is much more "confusing" than in classic OO languages.

Let’s take a look at what’s confusing about the various ways of using this in JavaScript?

1. Use this keyword inline mode in the HTML element event attribute:

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

The most commonly used method is to use it here: javascirpt: EventHandler(this), in this form. However, you can actually write any legal JavaScript statement here. If you like, you can define a class here (but it will be an inner class). The principle here is that the script engine generates an anonymous member method of the p instance object, and onclick points to this method.

2. Use the DOM method to use the this keyword in the event processing function:

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
 }
 
// -->
Copy after login

At this time, this in the EventHandler() method Keyword, the indicated object is IE's window object. This is because EventHandler is just an ordinary function. After attachEvent, the script engine's call to it has nothing to do with the p object itself. At the same time, you can look at the caller attribute of EventHandler, which is equal to null. If we want to get the p object reference in this method, we should use: this.event.srcElement.

3. Use DHTML to use the this keyword in the event processing function:

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
 };
 
// -->
Copy after login

The content indicated by the this keyword here is the p element object instance. In the script Using DHTML to directly assign an EventHandler method to p.onclick is equivalent to adding a member method to the p object instance. The difference between this method and the first method is that the first method uses the HTML method, and here is the DHTML method. The script parsing engine in the latter will no longer generate anonymous methods.

4. Use this keyword in class definition:

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();
Copy after login

这是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());
Copy after login

这里的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();
Copy after login

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

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

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

这里的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()();
Copy after login

运行结果显示是:"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
Copy after login

以上归纳出的三类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();
  
// -->
Copy after login

上面的代码执行结果是:

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

页面上显示

 func variable!
 new element
Copy after login

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

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

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

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

The above is the detailed content of Understanding the this keyword in js. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template