Helah this_javascript yang menakjubkan dalam Javascript
Ini dalam Javascript adalah mekanisme yang sama sekali berbeza daripada bahasa lain, yang mungkin mengelirukan sesetengah jurutera yang menulis bahasa lain.
1. Tersalah anggap bahawa ini menunjukkan fungsi itu sendiri
Menurut tatabahasa bahasa Inggeris ini, adalah mudah untuk memahami perkara ini muncul dalam fungsi sebagai fungsi itu sendiri. Dalam JavaScript, fungsi adalah warga kelas pertama dan sememangnya boleh menyimpan nilai atribut apabila dipanggil. Tetapi jika anda menggunakannya secara tidak betul, ia boleh menyebabkan ketidakselarasan dengan jangkaan sebenar. Untuk keadaan tertentu, sila lihat kod di bawah
function fn(num){ this.count++; } fn.count = 0; for(var i=0;i<3;i++){ fn(i); } console.log(fn.count); // 0
Jika ini dalam fungsi fn menunjuk ke fungsinya sendiri, maka nilai atribut atribut count harus berubah, tetapi sebenarnya ia kekal tidak berubah. Untuk masalah ini, sesetengah orang akan menggunakan skop untuk menyelesaikannya, seperti menulis
var data = { count:0 }; function fn(num){ data.count++; } for(var i=0;i<3;i++){ fn(i); } console.log(data.count); //3
Atau lebih lanjut secara langsung,
function fn(num){ fn.count++; } fn.count = 0; for(var i=0;i<3;i++){ fn(i); } console.log(fn.count);//3
Walaupun kedua-dua kaedah menghasilkan keputusan yang betul, ia mengelakkan masalah di mana ini terikat. Jika prinsip kerja sesuatu perkara tidak jelas, ia selalunya akan membawa kepada sakit kepala dan sakit, mengakibatkan kod hodoh dan kebolehselenggaraan yang lemah.
2. Peraturan mengikat ajaib ini
2.1 Peraturan mengikat lalai
Yang pertama adalah yang paling biasa pengikatan ini, lihat kod di bawah
function fn(){ console.log(window === this); //浏览器环境 } fn(); //true
Fungsi fn dipanggil terus dalam skop global tanpa sebarang pengubahsuaian lain Dalam kes ini, pengikatan lalai ini digunakan apabila fungsi dipanggil, menunjuk ke objek global.
Ini menjelaskan dengan jelas bahawa ini dalam contoh pertama menunjukkan pembolehubah global dalam fungsi fn, jadi this.count adalah bersamaan dengan window.count (dalam persekitaran penyemak imbas), dan sudah tentu ia tidak menjejaskan kiraan fungsi fn mempunyai kesan.
Satu perkara yang perlu diambil perhatian ialah situasi di atas hanya boleh berlaku dalam mod tidak ketat (mod ketat, ini akan terikat kepada tidak ditentukan secara lalai). Untuk mengelakkan pencemaran pembolehubah global.
2.2 Peraturan mengikat tersirat
Jika fungsi dipanggil dengan objek sebagai konteks, pengikatan ini akan berubah. ini akan terikat pada objek yang memanggil fungsi ini, lihat kod berikut:
var obj = { a:1, fn:function(){ console.log(this.a); } } obj.fn(); //1
Walaupun pengisytiharan fungsi tiada dalam objek, penunjuk ini masih akan berubah
function fn(){ console.log(this.a); } var obj = { a:1, fn:fn } obj.fn(); //1
Ia boleh dilihat bahawa pengikatan ini tidak berkaitan dengan lokasi definisi fungsi, tetapi dengan pemanggil dan kaedah panggilan.
Di bawah peraturan mengikat tersirat, terdapat beberapa perkara istimewa yang perlu diberi perhatian.
2.2.1 Objek berbilang lapisan memanggil penunjuk ini
function fn(){ console.log(this.a); } var obj = { a:1, obj2:obj2 } var obj2 = { a:2, obj3:obj3 } var obj3 = { a:3, fn:fn } obj.obj2.obj3.fn(); //3
Di bawah rujukan objek berbilang peringkat, ini menunjukkan kepada objek fungsi yang dipanggil.
2.2.2 Tugasan tersirat mungkin hilang
Lihat kod di bawah
function fn(){ console.log(this); } var obj = { fn:fn } var fun = obj.fn; fun(); //window
Walaupun fn merujuk kepada obj.fun, kaedah memanggil fungsi masih tanpa sebarang pengubahsuaian, jadi ini masih terikat pada tetingkap.
Terdapat satu lagi situasi yang mudah untuk semua orang terlepas pandang, iaitu, apabila lulus parameter, tugasan tersirat sebenarnya akan dilakukan.
function fn(){ console.log(this); } function doFn(fn){ fn(); } var obj = { fn:fn } doFn(obj.fn); //window
Pengikatan tersirat ini bukanlah kaedah yang sangat disyorkan, kerana ia berkemungkinan besar akan hilang Jika terdapat keperluan untuk pengikatan ini dalam perniagaan, adalah disyorkan untuk menggunakan pengikatan eksplisit.
2.3 Peraturan mengikat yang jelas
Ikatan eksplisit menggunakan kaedah guna dan panggil pada prototaip fungsi untuk mengikat ini. Penggunaannya adalah untuk lulus objek yang anda ingin ikat sebagai parameter pertama.
function fn(){ console.log(this); } var obj = {}; fn.call(obj); //{}
Kadangkala anda ingin mengikat fungsi ini pada objek, tetapi tidak perlu memanggilnya dengan segera. Dalam kes ini, ia tidak boleh dilakukan secara langsung menggunakan panggilan atau gunakan.
function fn(){ console.log(this); } function bind(fn){ fn(); } var obj = { fn:fn } bind.call(obj,fn); //window
Contoh di atas nampaknya berfungsi, tetapi sebenarnya, fungsi bind ini terikat pada objek obj, tetapi fn masih dipanggil tanpa sebarang pengubahsuaian, jadi fn masih merupakan kaedah pengikatan lalai.
function fn(){ console.log(this); } function bind(fn,obj){ return function(){ fn.apply(obj,arguments); } } var obj = { fn:fn } var fun = bind(fn,obj); fun(); //obj
这样调用,就可以将灵活多变的 this ,牢牢的控制住了,因为 fn 的调用方式为 apply 调用。所以,this 就被绑定在传入的 obj 对象上,在 ES5 当中,函数的原型方法上多了一个 bind。效果与上面的函数基本一致,具体用法限于篇幅就不多说了。
2.4 new 绑定
new 是一个被很多人误解的一个关键字,但实际上 javascript 的 new 与传统面向对象的语言完全不同。
个人把 new 理解为一种特殊的函数调用,当使用 new 关键字来调用函数的时候,会执行下面操作,
- 创建一个全新的对象
- 将空对象的 __proto__ 指向构造函数的 prototype
- 将新对象的 this 绑定到调用的函数上
- 如果函数返回值为基本类型或者为 this又或者不返回任何值,那么将会返回这个创建的新对象,如果返回了一个对象,那么则会返回这个对象,而不会返回创建的新对象。
function fn(a){ this.a = a; } fn.prototype.hi = function(){ console.log('hi') } var obj = new fn(2); console.log(obj); function fn(a){ this.a = a; return {}; } var obj = new fn(2); console.log(obj); //{}
2.5 特殊的传参
null 和 undefined 也是可以作为 this 的绑定对象的,但是实际上应用的是默认的绑定。
但是这种传参的实际效用是什么呢?
常见的用法是将一个数组展开,作为参数传入参数。比如
function fn(a,b){ console.log('a:',a,'b:',b); } fn.apply(null,[1,2]); // a: 1 b: 2
但是这种用法会有一个坑,那就是如果函数存在了 this ,那么就会应用默认的绑定规则,将 this 绑定在全局对象上,发生于预期不一致的情况。为了代码更加稳健,可以使创建一个比空对象更空的对象。
var obj = Object.create(null); console.log(obj.__proto__); //undefined var obj2 = {} console.log(obj2.__proto__); //Object {}
Object原型上有一个 create 方法,这个方法会创建一个对象,然后将对象的原型指向传入的参数,所以传入 null 的话,产生一个没有 prototype 的对象,所以会比空对象更加"空"。
所以传入这个对象,会比传入 null 更加安全。
var obj = Object.create(null); fn.apply(obj,[1,2]);
2.6 根据作用域来决定 this 的绑定
在 ES6 当中,出现了一个新的函数类型,箭头函数。
如果使用箭头函数,那么就不会使用上面提到的四种 this 绑定方式,而是根据作用域来决定
比较常见的是用于事件函数和定时器的情况。
下面是比较常见的传统 this 写法
function fn(){ var _this = this; setTimeout(function(){ console.log(_this.a); },100) } var obj = { a:2 } fn.call(obj); //2
如果使用箭头函数则可以这么写
function fn(){ setTimeout(()=>{ //this 来源于 fn 函数的作用域 console.log(this.a); },100) } var obj = { a:2 } fn.call(obj); //2
2.7 事件函数当中 this 的绑定机制
如果是在事件函数当中,this 的绑定是指向触发事件的 DOM 元素的,
$('body')[0].addEventListener('click',function(){ console.log(this); },false);
点击 body 元素之后,控制台则会显示 body 元素
3. 小结
如果想判断一个函数的 this 绑定在哪里,首先是找到函数的调用位置,之后是按照规则来判断。
- 如果函数调用时没有任何修饰条件,那么在严格模式下则会绑定到 undefined ,非严格模式下会绑定到全局。
- 如果是用对象做上下文,来对函数进行调用,那么则会绑定到调用的这个对象上。
- 如果是用 call 或者 apply 方法来进行调用的,则会绑定到第一个传入参数上。
- 如果是使用 new 关键字来调用函数的,则会绑定到新创建的那个对象上.
- 如果是在事件函数内,则会绑定到触发事件的那个DOM元素上。
以上就是关于Javascript中神奇的this的相关介绍,希望对大家的学习有所帮助。

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut
