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); }
严格模式下指向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(); // 2
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(); // 1
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); // 1
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); // 1
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; // 2