Rumah  >  Artikel  >  hujung hadapan web  >  Apakah keajaiban ini dalam JavaScript?

Apakah keajaiban ini dalam JavaScript?

藏色散人
藏色散人ke hadapan
2021-09-19 17:11:481919semak imbas
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.

Bukan ini, bukan itu, apa ini?

在函数执行过程中,会创建一个执行上下文(一个记录),this就是这个上下文中的一个属性,在执行过程中用到。而this的指向则是取决于函数在哪里被调用。

Peraturan mengikat untuk ini

Terdapat empat peraturan yang boleh diikuti untuk mengikat ini, yang akan diperkenalkan satu demi satu di bawah.

1. Pengikatan lalai

Fungsi bebas yang disebut di sini boleh difahami sebagai panggilan fungsi umum kecuali untuk tiga situasi berikut. 独立函数调用,非严格模式下,指向window;严格模式下指向undefined。

// 非严格模式
var name = &#39;Willem&#39;;
function foo() {
    console.log(this.name);
}
foo(); // Willem

// 执行时启用严格模式
(function() {
    &#39;use strict&#39;;
    foo(); // Willem
    bar(); // Cannot read property &#39;name&#39; of undefined
})();

// 函数体使用严格模式
function bar() {
    &#39;use strict&#39;;
    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指的是函数体内启用了严格模式,而不是调用时。

2. Pengikatan tersirat

Pengikatan tersirat,

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

Ramai rakan hadapan mungkin pernah melihat soalan ini semasa temu bual:

function foo() {
    console.log(this.a);
}
var a = 1;
var obj = {
    a: 2,
    foo
};
var bar = obj.foo;
bar(); // 1
Ini 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

Terdapat juga fungsi panggil balik klasik masalah penunjuk ini yang juga hilang secara tersirat.

function foo() {
    console.log(this.a);
}
function doFoo(fn) {
    fn();
}
var a = 1;
var obj = {
    a: 2,
    foo
};
doFoo(obj.foo); // 1
Ringkasan: 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); // 1
Walaupun 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函数)

4. baru

Perkara terakhir yang ingin saya perkenalkan ialah menggunakan

untuk mengubah suai pengikatan Kasut kanak-kanak yang telah dilaksanakan secara manual dengan lebih jelas js Bahasa baharu adalah berbeza sama sekali. newProses pelaksanaan baharu:

    Buat objek kosong
  1. Objek kosong semasa melakukan dok prototaip
  2. Kembalikan hasil pelaksanaan fungsi atau kosong semasa objek
function Foo(a) {
    this.a = a;
}

var bar = new Foo(2);
bar.a; // 2
Apabila menggunakan baharu untuk memanggil fungsi, kami akan membina objek baharu dan mengikatnya dengan ini dalam panggilan fungsi.

Keutamaan

Akhir sekali, mari kita bincangkan secara ringkas tentang hubungan keutamaan: pengikatan paparan tersirat >

Kajian yang disyorkan: "

Tutorial Asas JavaScript"

Atas ialah kandungan terperinci Apakah keajaiban ini dalam JavaScript?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:segmentfault.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam