Kata kunci ini ialah salah satu mekanisme yang paling kompleks dalam JavaScript. Ia adalah kata kunci yang sangat istimewa yang ditakrifkan secara automatik dalam skop semua fungsi. Tetapi pembangun JavaScript yang sangat berpengalaman pun mengalami kesukaran untuk mengetahui apa sebenarnya yang dituju.
Apakah ini?
menunjuk kepada fungsi itu sendiri?
Melihat makna literal, mudah untuk berfikir bahawa ini menunjuk kepada fungsi itu sendiri. Adakah ini benar-benar berlaku? Kita boleh lihat contoh.
function foo() { this.count = this.count ? this.count + 1 : 1; } for (let i = 0; i < 5; i++) { foo(); } console.log(foo.count); // undefined
Seperti yang anda boleh lihat, output foo.count bukanlah 5
yang kami jangkakan, tetapi 0
yang ditetapkan pada mulanya. Dalam erti kata lain, ini sebenarnya tidak menunjuk kepada fungsi itu sendiri .
menunjuk ke skop?
Satu lagi salah faham yang biasa ialah ini menunjukkan skop fungsi.
function foo() { var a = 2; bar(); } function bar() { console.log(this.a); } foo(); // undefined
Dalam kod ini, bar dijalankan dalam foo dan output this.a
ialah undefined
. Dalam erti kata lain, ini tidak menunjuk kepada skop fungsi.
在函数执行过程中,会创建一个执行上下文(一个记录),this就是这个上下文中的一个属性,在执行过程中用到。而this的指向则是取决于函数在哪里被调用。
Fungsi bebas yang disebut di sini boleh difahami sebagai panggilan fungsi umum kecuali untuk tiga situasi berikut. 独立函数调用,非严格模式下,指向window;严格模式下指向undefined。
// 非严格模式 var name = 'Willem'; function foo() { console.log(this.name); } foo(); // Willem // 执行时启用严格模式 (function() { 'use strict'; foo(); // Willem bar(); // Cannot read property 'name' of undefined })(); // 函数体使用严格模式 function bar() { 'use strict'; console.log(this.name); }Dalam kod di atas, Willem dikeluarkan dalam persekitaran biasa, menunjukkan bahawa ia sememangnya objek tetingkap yang ditunjuk. Satu perkara yang memerlukan perhatian khusus ialah:
严格模式下指向undefined指的是函数体内启用了严格模式,而不是调用时。
. Dalam erti kata lain, apabila fungsi sedang berjalan, ia tidak begitu jelas sama ada ia dijalankan sebagai atribut objek Berikut ialah contoh: 在函数执行时,是否被某个对象拥有或包含
function foo() { console.log(this.a); } var a = 1; var obj = { a: 2, foo }; obj.foo(); // 2 var obj2 = { a: 3, obj }; obj2.obj.foo(); // 2Dalam contoh, foo dianggap sebagai obj An. atribut fungsi dilaksanakan Pada masa ini, obj berfungsi sebagai konteks fungsi Pada masa ini, ini menunjuk kepada
bersamaan dengan this.a
. Dalam panggilan rantaian sifat objek, hanya lapisan terakhir akan mempengaruhi kedudukan panggilan, yang bermaksud bahawa lapisan terakhir akan mempengaruhi titik ini. obj.a
function foo() { console.log(this.a); } var a = 1; var obj = { a: 2, foo }; var bar = obj.foo; bar(); // 1Ini adalah masalah paling biasa dengan pengikatan tersirat,
Kehilangan tersirat: Fungsi terikat secara tersirat akan kehilangan objek pengikat . Walaupun bar ialah rujukan kepada obj.foo, ia sebenarnya merujuk kepada fungsi foo itu sendiri Fungsi bar ialah panggilan ke fungsi bebas Rujuk kepada item pertama, pada masa ini . this指向了window|undefined
function foo() { console.log(this.a); } function doFoo(fn) { fn(); } var a = 1; var obj = { a: 2, foo }; doFoo(obj.foo); // 1Ringkasan: Dalam pengikatan tersirat, apabila memberikan nilai (panggilan balik adalah tugasan tersirat), perhatian khusus perlu diberikan kepada masalah kehilangan tersirat. 3. Ikatan paparan Fungsi dalam JavaScript menyediakan dua kaedah
dan call
Parameter pertama yang dihantar ialah objek, yang akan mengikat ini dengan objek ini. Jika nilai primitif (rentetan, nombor, Boolean) dihantar, ia akan ditukar kepada bentuk objeknya (String baharu), Boolean baharu (), Nombor baharu ()). apply
function foo() { console.log(this.a); } var obj = { a: 1 }; foo.call(obj); // 1Walaupun kita boleh menggunakan
dan call
untuk menyatakan secara eksplisit perkara ini, masih akan ada masalah kehilangan ikatan. Ia boleh diselesaikan dengan apa yang dipanggil apply
, jadi saya tidak akan menerangkan butiran di sini. 硬绑定(bind函数)
untuk mengubah suai pengikatan Kasut kanak-kanak yang telah dilaksanakan secara manual dengan lebih jelas js Bahasa baharu adalah berbeza sama sekali. new
Proses pelaksanaan baharu:
- Buat objek kosongObjek kosong semasa melakukan dok prototaipKembalikan hasil pelaksanaan fungsi atau kosong semasa objek
function Foo(a) { this.a = a; } var bar = new Foo(2); bar.a; // 2Apabila menggunakan baharu untuk memanggil fungsi, kami akan membina objek baharu dan mengikatnya dengan ini dalam panggilan fungsi. KeutamaanAkhir sekali, mari kita bincangkan secara ringkas tentang hubungan keutamaan: pengikatan paparan tersirat > Kajian yang disyorkan: "