Cara untuk mengakses objek `ini` dengan betul dalam fungsi panggil balik
P粉608647033
P粉608647033 2023-08-20 16:11:32
0
2
551
<p>Saya mempunyai pembina yang mendaftarkan pengendali acara: </p> <p><br /></p> <pre class="snippet-code-js lang-js prettyprint-override"><kod>fungsi MyConstructor(data, pengangkutan) { ini.data = data; transport.on('data', fungsi () { alert(this.data); }); } //Simulasikan objek pemindahan pengangkutan var = { on: function(event, callback) { setTimeout(panggilan balik, 1000); } }; // Kaedah panggilan var obj = MyConstructor('foo', transport);</code></pre> <p><br /></p> <p>Walau bagaimanapun, dalam fungsi panggil balik saya tidak boleh mengakses sifat <kod>data</code> Nampaknya <kod>ini</kod> tidak menghala ke objek yang dicipta, tetapi ke objek lain. </p> <p>Saya juga cuba menggunakan kaedah objek dan bukannya fungsi tanpa nama: </p> <pre class="brush:php;toolbar:false;">function MyConstructor(data, transport) { ini.data = data; transport.on('data', this.alert); } MyConstructor.prototype.alert = function() { makluman(nama.ini); };</pre> <p>Tetapi ia juga mempunyai masalah yang sama. </p> <p>Bagaimanakah saya boleh mengakses objek yang betul? </p>
P粉608647033
P粉608647033

membalas semua(2)
P粉921130067

Berikut ialah beberapa cara untuk mengakses konteks ibu bapa dalam konteks kanak-kanak:

  1. Anda boleh menggunakan fungsi bind().
  2. Simpan rujukan kepada konteks/ini dalam pembolehubah lain (lihat contoh di bawah).
  3. Gunakan fungsi anak panah ES6.
  4. Ubah suai kod, reka bentuk fungsi dan seni bina - untuk ini anda harus menguasai Corak Reka Bentuk dalam JavaScript.

1. Guna bind()fungsi

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', ( function () {
        alert(this.data);
    }).bind(this) );
}
// 模拟传输对象
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// 调用方式
var obj = new MyConstructor('foo', transport);

Jika anda menggunakan Underscore.js - http://underscorejs.org/#bind

transport.on('data', _.bind(function () {
    alert(this.data);
}, this));

2 Simpan rujukan konteks/ini dalam pembolehubah lain

function MyConstructor(data, transport) {
  var self = this;
  this.data = data;
  transport.on('data', function() {
    alert(self.data);
  });
}

3. Fungsi anak panah

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}
P粉176151589

Pengetahuan tentang this

this (juga dipanggil "konteks") ialah kata kunci khas di dalam setiap fungsi yang nilainya bergantung hanya pada cara fungsi dipanggil, bukan bagaimana ia ditakrifkan. Ia tidak dipengaruhi oleh skop leksikal, tidak seperti pembolehubah lain (kecuali fungsi anak panah, lihat di bawah). Berikut adalah beberapa contoh:

function foo() {
    console.log(this);
}

// 普通函数调用
foo(); // `this` 将引用 `window`

// 作为对象方法
var obj = {bar: foo};
obj.bar(); // `this` 将引用 `obj`

// 作为构造函数
new foo(); // `this` 将引用从 `foo.prototype` 继承的对象

Untuk mengetahui lebih lanjut tentang this, sila rujuk dokumentasi MDN.


Cara petik yang betul this

Gunakan fungsi anak panah

ECMAScript 6 memperkenalkan fungsi anak panah, yang boleh dianggap sebagai fungsi lambda. Mereka tidak mempunyai ikatan this绑定。相反,this在作用域中查找,就像普通变量一样。这意味着你不需要调用.bind mereka sendiri. Sebaliknya,

dilihat dalam skop, sama seperti pembolehubah biasa. Ini bermakna anda tidak perlu memanggil .bind. Mereka juga mempunyai tingkah laku istimewa lain, lihat dokumentasi MDN untuk maklumat lanjut.

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', () => alert(this.data));
}
thisTidak digunakan

this,而是需要访问它所指的对象。因此,一个简单的解决方案是创建一个新变量,也指向该对象。变量可以有任何名称,但常见的是selfthatSebenarnya, anda tidak perlu mengakses

secara khusus, sebaliknya objek yang dirujuknya. Jadi penyelesaian mudah adalah untuk mencipta pembolehubah baru yang juga menunjuk ke objek. Pembolehubah boleh mempunyai sebarang nama, tetapi yang biasa ialah diri dan that.

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function() {
        alert(self.data);
    });
}
self是一个普通变量,它遵循词法作用域规则,并且可以在回调函数内部访问。这还有一个优点,即可以访问回调函数本身的thisMemandangkan self ialah pembolehubah biasa, ia mengikut peraturan skop leksikal dan boleh diakses di dalam fungsi panggil balik. Ini juga mempunyai kelebihan untuk mempunyai akses kepada nilai fungsi panggil balik itu sendiri.

thisMenetapkan fungsi panggil balik secara eksplisit

- Bahagian 1

thisNampaknya anda tidak mempunyai kawalan ke atas nilai

kerana nilainya ditetapkan secara automatik, tetapi sebenarnya tidak begitu.

Setiap fungsi mempunyai kaedah .bind [文档],它返回一个将this绑定到一个值的新函数。该函数的行为与你调用.bind时的函数完全相同,只是this由你设置。无论如何或何时调用该函数,this.bind

[docs]this绑定到MyConstructorthis

, yang mengembalikan fungsi baharu yang mengikat kepada nilai. Gelagat fungsi ini adalah sama seperti semasa anda memanggil .bind, kecuali ia ditetapkan oleh anda. Tidak kira atau apabila fungsi dipanggil, akan sentiasa merujuk kepada nilai yang diluluskan.

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // 括号不是必需的
        alert(this.data);             // 但可能提高可读性
    }).bind(this); // <- 这里我们调用了`.bind()`
    transport.on('data', boundFunction);
}
jQuery.proxyDalam kes ini, kami mengikat fungsi panggil balik kepada nilai MyConstructor. Nota:

Untuk konteks mengikat jQuery, gunakan 🎜🎜 🎜🎜[Dokumentasi]🎜🎜🎜. Sebab untuk ini ialah tidak perlu menyimpan rujukan kepada fungsi apabila menyahikat panggilan balik acara. jQuery mengendalikan ini secara dalaman. 🎜

Sediakan fungsi panggil balikthis - Bahagian 2

Sesetengah fungsi/kaedah yang menerima fungsi panggil balik juga menerima nilai yang harus digunakan sebagai this。这与手动绑定相同,但是函数/方法会为你执行绑定。例如,Array#map fungsi panggil balik. Ini adalah sama seperti pengikatan manual, tetapi fungsi/kaedah melaksanakan pengikatan untuk anda. Contohnya, Array#map kod > [Dokumentasi]Ini kaedahnya. Tandatangannya ialah:

array.map(callback[, thisArg])

Parameter pertama ialah fungsi panggil balik, dan parameter kedua ialah nilai yang thissepatutnya dirujuk. Berikut ialah contoh rekaan:

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
    return v * this.multiplier;
}, obj); // <- 这里我们将`obj`作为第二个参数传递

Nota: Sama ada boleh lulus nilai this的值通常在函数/方法的文档中提到。例如,jQuery的$.ajax方法 [文档]描述了一个名为context biasanya disebut dalam dokumentasi fungsi/kaedah. Contohnya, kaedah $.ajax jQuery


[Dokumentasi]

Penerangan Pilihan yang dipanggil konteks:

Soalan Lazim: Menggunakan kaedah objek sebagai panggilan balik/pengendali acara

this.method被分配为点击事件处理程序,但是如果点击document.body,记录的值将是undefined,因为在事件处理程序内部,this指的是document.body,而不是FooSatu lagi manifestasi biasa masalah ini ialah menggunakan kaedah objek sebagai panggilan balik/pengendali acara. Dalam JavaScript, fungsi adalah warga kelas pertama, dan istilah "kaedah" hanya merujuk kepada fungsi yang merupakan nilai harta objek. Tetapi tidak ada pautan khusus antara fungsi dan objek "mengandungi"nya.
thisPertimbangkan contoh berikut:

function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = function() {
    console.log(this.data);
};
Fungsi this.method diperuntukkan sebagai pengendali acara klik, tetapi jika document.body diklik, nilai yang direkodkan akan menjadi undefined kerana dalam Di dalam pengendali acara, merujuk kepada document.body, bukan contoh Foo. Seperti yang dinyatakan sebelum ini,
merujuk kepada bagaimana fungsi

dipanggil

, bukan bagaimana ditakrifkan . .bindthis Ia mungkin lebih jelas jika kod kelihatan seperti ini:

function method() {
    console.log(this.data);
}


function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = method;

🎜Penyelesaian 🎜 adalah sama seperti yang dinyatakan di atas: gunakan .bind untuk mengikat secara eksplisit 🎜 kepada nilai tertentu 🎜 jika tersedia

document.body.onclick = this.method.bind(this);
🎜Atau dengan menggunakan fungsi tanpa nama sebagai panggilan balik/acara
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan