搜尋
首頁web前端js教程關於js裡的this關鍵字的理解_javascript技巧

this關鍵字在c ,java中都提供了這個關鍵字,在剛開始學習時覺得有難度,但是只要理解了,用起來就方便多了,下面透過本篇文章給大家詳解js裡this關鍵字的理解。

關於this,是很多前端面試必考的題目,有時候在網路上看到這些題目,自己試了一下,額,還真的錯了!在實際開發中,也會遇到this 的問題(雖然有些類別庫會幫我們處理),例如在使用一些框架的時候,例如:knockout,有時候不明白為什麼不直接使用this,而要把this 作為參數傳入。

   接下來你談談我對它的理解,也作為一個筆記,方便以後參閱。有不對的地方,歡迎指出批評。

   1. 不像C#,this一定是指向目前物件。

js的this指向是不確定的,也就是說是可以動態改變的。 call/apply 就是用來改變this指向的函數,這樣設計可以讓程式碼更有彈性,多用性更高。

   2. this 一般情況下,都是指向函數的擁有者。

這一點很重要!這一點很重要!這一點很重要!

   這也是一道常見的面試題,如下碼:

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

  由於showNumber方法的擁有者是obj,所以this.number=3; this 指向的就是 obj 的屬性 number。

  同理,第二個 console.log 印刷的也是屬性 number。

   為什麼第二點說一般情況下this都是指向函數的擁有者,因為有特殊情況。函數自執行就是特殊情況,在函數自執行裡,this 指向的是:window。所以第一個 console.log 印製的是 window 的屬性 number。

   所以再加一點:

   3. 在函數自執行裡,this 指向的是 window 物件。

   擴展,關於this,還有一個地方比較讓人模糊的是在 dom 事件裡,通常有如下3種情況:

   如下:

   1. 使用標籤屬性註冊事件,此時​​this 指向的是 window 物件。

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

   2. 對於1,要讓 this 指向 input,可以將 this 作為參數傳遞。

   3. 使用 addEventListener 等註冊。此時this 也是指向 input。

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

   在物件導向程式語言中,對於this關鍵字我們是非常熟悉的。例如C 、C#和Java等都提供了這個關鍵字,雖然在開始學習的時候覺得比較難,但只要理解了,用起來是非常方便和意義確定的。 JavaScript也提供了這個this關鍵字,不過用起來就比經典OO語言中要"混亂"的多了。

  下面就來看看,在JavaScript中各種this的使用方法有什麼混亂之處?

  1.在HTML元素事件屬性中inline方式使用this關鍵字:

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

我們一般比較常用的方法是在此使用:javascirpt: EventHandler(this),這樣的形式。不過這裡其實可以寫任何合法的JavaScript語句,要是高興在此定義個類別也可以(不過將會是個內部類別)。這裡的原理是腳本引擎產生了一個div實例物件的匿名成員方法,而onclick指向這個方法。

   2、用DOM方式在事件處理函數中使用this關鍵字:

division element

 var div = document.getElementById('elmtDiv');  
 div.attachEvent('onclick', EventHandler);  
 
 function EventHandler()  
 {  
 // 在此使用this  
 }  
  
// --> 
 
division element

 var div = document.getElementById('elmtDiv');
 div.attachEvent('onclick', EventHandler);

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

  這時的EventHandler()方法中的this關鍵字,指示的物件是IE的window物件。這是因為EventHandler只是一個普通的函數,而對於attachEvent後,腳本引擎對它的呼叫和div物件本身沒有任何的關係。同時你可以再看看EventHandler的caller屬性,它是等於null的。如果我們要在這個方法中獲得div物件引用,應該使用:this.event.srcElement。

  3、用DHTML方式在事件處理函數中使用this關鍵字:

division element
  
lt;mce:script language="javascript">
var div = document.getElementById('elmtDiv');  
div.onclick = function()  
{  
 // 在此使用this  
};  
 
/ --> 
 
division element

 var div = document.getElementById('elmtDiv');
 div.onclick = function()
 {
 // 在此使用this
 };
 
// --> 

  這裡的this關鍵字指示的內容是div元素物件實例,在腳本中使用DHTML方式直接為div.onclick賦值一個EventHandler的方法,等於為div物件實例新增一個成員方法。這種方式和第一種方法的差異是,第一種方法是使用HTML方式,而這裡是DHTML方式,後者腳本解析引擎不會再產生匿名方法。

  4、類別定義中使用this關鍵字:

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

 JSClass.prototype.ToString = function()
 {
 alert(myName + ', ' + 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('('));  
fnName = fnName.replace(/^function/, '');  
return fnName.replace(/(^\s+)|(\s+$)/g, '');  
}  
function foo(){}  
alert(foo.GetName());  
 function.prototype.GetName = function()
 {
 var fnName = this.toString(); 
 fnName = fnName.substr(0, fnName.indexOf('(')); 
 fnName = fnName.replace(/^function/, ''); 
 return fnName.replace(/(^\s+)|(\s+$)/g, '');
 }
 function foo(){}
 alert(foo.GetName()); 

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

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

view plaincopy to clipboardprint&#63;
function JSClass()  
{  
this.m_Text = 'division element';  
this.m_Element = document.createElement('DIV');  
this.m_Element.innerHTML = this.m_Text;  
  
this.m_Element.attachEvent('onclick', 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 = 'division element';
 this.m_Element = document.createElement('DIV');
 this.m_Element.innerHTML = this.m_Text;
  
 this.m_Element.attachEvent('onclick', 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(); 

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

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

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

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

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

view plaincopy to clipboardprint&#63;
function OuterFoo()  
{  
this.Name = 'Outer Name';  
 
function InnerFoo()  
{  
var Name = 'Inner Name';  
alert(Name + ', ' + this.Name);  
}  
return InnerFoo;  
}  
OuterFoo()(); 
 function OuterFoo()
 {
 this.Name = 'Outer Name';
 
 function InnerFoo()
 {
 var Name = 'Inner Name'; 
 alert(Name + ', ' + 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指向div元素对象实例

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

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

view plaincopy to clipboardprint&#63;

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

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

view plaincopy to clipboardprint&#63;

    function JSClass()  
    {  
      var varText = "func variable!";                 //函数中的普通变量  
      this.m_Text = 'func member!';                    //函数类的成员变量  
      this.m_Element = document.createElement('DIV');   //成员变量,创建一个div对象  
      this.m_Element.innerHTML = varText;             //使用函数的普通变量  
      this.m_Element.attachEvent('onclick', this.ToString);  //给这个对象的事件连上处理函数  
      this.newElement = document.createElement('DIV');  
      this.newElement.innerHTML = "new element";   
      this.newElement.m_Text = "new element text!";      //给创建的对象建个成员  
      this.newElement.onclick = function()  
      {  
        alert(this.m_Text);                       //指向div对象的成员  
      };  
    }  
   
    JSClass.prototype.Render = function()  
    {  
      document.body.appendChild(this.m_Element);       //把div对象挂在窗口上  
      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 = 'func member!';     //函数类的成员变量
    this.m_Element = document.createElement('DIV'); //成员变量,创建一个div对象
    this.m_Element.innerHTML = varText;    //使用函数的普通变量
    this.m_Element.attachEvent('onclick', this.ToString); //给这个对象的事件连上处理函数
    this.newElement = document.createElement('DIV');
    this.newElement.innerHTML = "new element"; 
    this.newElement.m_Text = "new element text!";  //给创建的对象建个成员
    this.newElement.onclick = function()
   {
     alert(this.m_Text);      //指向div对象的成员
   };
  }
  
  JSClass.prototype.Render = function()
  {
    document.body.appendChild(this.m_Element);  //把div对象挂在窗口上
    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指针指向div元素,而该元素已经定义了m_Text成员(this.newElement.m_Text = "new element text!")

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。