Kata kunci ini disediakan dalam kedua-dua c dan java Ia adalah sukar apabila anda mula-mula belajar, tetapi apabila anda memahaminya, ia akan menjadi lebih mudah untuk digunakan Berikut adalah penjelasan terperinci tentang ini dalam js melalui artikel ini .
Mengenai perkara ini, ia adalah soalan yang diperlukan untuk banyak temu duga bahagian hadapan Kadang-kadang saya melihat soalan ini di Internet dan mencubanya sendiri, saya benar-benar salah! Dalam pembangunan sebenar, kami juga akan menghadapi masalah ini (walaupun sesetengah perpustakaan kelas akan membantu kami menanganinya. Contohnya, apabila menggunakan beberapa rangka kerja, seperti: kalah mati, kadangkala kami tidak faham mengapa kami tidak menggunakannya secara langsung). , tetapi gunakan ini sebagai Parameter dihantar masuk.
Seterusnya, anda bercakap tentang pemahaman saya tentangnya, dan juga sebagai nota untuk rujukan masa hadapan. Kalau ada salah sila tunjuk dan kritik.
1. Tidak seperti C#, ini mesti menunjuk ke objek semasa.
Titik js ini tidak pasti, yang bermaksud ia boleh ditukar secara dinamik. call/apply ialah fungsi yang digunakan untuk menukar titik yang ditunjukkan oleh ini Reka bentuk ini boleh menjadikan kod lebih fleksibel dan boleh digunakan semula.
2. Ini biasanya menunjuk kepada pemilik fungsi.
Ini sangat penting! Ini sangat penting! Ini sangat penting!
Ini juga soalan temuduga biasa, kodnya adalah seperti berikut:
<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>
Memandangkan pemilik kaedah showNumber ialah obj, maka ini.number=3;
Begitu juga, console.log kedua juga mencetak nombor atribut.
Mengapa titik kedua mengatakan bahawa secara amnya ini menunjukkan kepada pemilik fungsi, kerana terdapat keadaan khusus. Pelaksanaan kendiri fungsi ialah kes khas Dalam pelaksanaan kendiri fungsi, ini menunjukkan: tetingkap. Jadi console.log pertama mencetak nombor atribut tetingkap.
Jadi saya perlu menambah sedikit:
3. Dalam fungsi pelaksanaan kendiri, ini menunjuk ke objek tetingkap.
Sambungan, berkenaan perkara ini, satu lagi perkara yang agak mengelirukan ialah dalam acara dom, biasanya terdapat tiga situasi:
seperti berikut:
1. Gunakan atribut label untuk mendaftarkan acara Pada masa ini, ini menghala ke objek tetingkap.
<input id="test" type="button" value="按钮" onClick="test()"/> function test(){alert(this)}
2. Untuk 1, untuk membuat titik ini pada input, anda boleh menghantar ini sebagai parameter.
3. Daftar menggunakan addEventListener dll. Pada masa ini ini juga menunjuk kepada input.
document.getElementById("test").addEventListener("click",test);
Dalam bahasa pengaturcaraan berorientasikan objek, kami sangat mengenali kata kunci ini. Sebagai contoh, C, C# dan Java semuanya menyediakan kata kunci ini Walaupun ia sukar pada permulaan pembelajaran, apabila anda memahaminya, ia sangat mudah dan bermakna untuk digunakan. JavaScript juga menyediakan kata kunci ini, tetapi ia lebih "mengelirukan" untuk digunakan berbanding dalam bahasa OO klasik.
Mari kita lihat apa yang mengelirukan tentang pelbagai cara menggunakan ini dalam JavaScript?
1. Gunakan kata kunci ini dalam baris dalam atribut acara elemen HTML:
// 可以在里面使用this ">division element // 可以在里面使用this ">division element
Kaedah paling biasa yang kami gunakan di sini ialah: javascirpt: EventHandler(this), dalam borang ini. Walau bagaimanapun, anda sebenarnya boleh menulis sebarang pernyataan JavaScript undang-undang di sini Jika anda suka, anda boleh menentukan kelas di sini (tetapi ia akan menjadi kelas dalaman). Prinsip di sini ialah enjin skrip menjana kaedah ahli tanpa nama bagi objek instance div, dan onclick menunjuk kepada kaedah ini.
2 Gunakan kaedah DOM untuk menggunakan kata kunci ini dalam fungsi pemprosesan acara:
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 } // -->
Pada masa ini, kata kunci ini dalam kaedah EventHandler() menunjukkan bahawa objek adalah objek tetingkap IE. Ini kerana EventHandler hanyalah fungsi biasa Selepas attachEvent, panggilan enjin skrip kepadanya tiada kaitan dengan objek div itu sendiri. Pada masa yang sama, anda boleh melihat atribut pemanggil EventHandler, yang sama dengan null. Jika kita ingin mendapatkan rujukan objek div dalam kaedah ini, kita harus menggunakan: this.event.srcElement.
3. Gunakan DHTML untuk menggunakan kata kunci ini dalam fungsi pemprosesan acara:
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 }; // -->
Kandungan yang ditunjukkan oleh kata kunci ini di sini ialah contoh objek elemen div Menggunakan DHTML dalam skrip untuk menetapkan kaedah EventHandler secara langsung kepada div.onclick adalah bersamaan dengan menambah kaedah ahli pada contoh objek div. Perbezaan antara kaedah ini dan kaedah pertama ialah kaedah pertama menggunakan kaedah HTML, dan di sini ialah kaedah DHTML Enjin penghuraian skrip dalam kaedah terakhir tidak lagi menjana kaedah tanpa nama.
4 Gunakan kata kunci ini dalam definisi kelas:
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? 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? 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? 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 = '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!")