Rumah > Soal Jawab > teks badan
Saya mempunyai pembina yang mendaftarkan pengendali acara:
function MyConstructor(data, transport) { this.data = data; transport.on('data', function () { alert(this.data); }); } // Mock transport object var transport = { on: function(event, callback) { setTimeout(callback, 1000); } }; // called as var obj = new MyConstructor('foo', transport);
Walau bagaimanapun, saya tidak boleh mengakses objek yang dibuat di dalam panggilan balik data
属性。看起来 this
yang tidak merujuk kepada objek yang dicipta tetapi kepada objek lain.
Saya juga cuba menggunakan kaedah objek dan bukannya fungsi tanpa nama:
function MyConstructor(data, transport) { this.data = data; transport.on('data', this.alert); } MyConstructor.prototype.alert = function() { alert(this.name); };
Tetapi ia juga mempunyai masalah yang sama.
Bagaimana untuk mengakses objek yang betul?
P粉3114235942023-10-12 09:02:51
绑定 a>()
. bind()
fungsifunction MyConstructor(data, transport) {
this.data = data;
transport.on('data', ( function () {
alert(this.data);
}).bind(this) );
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor('foo', transport);
Jika anda menggunakan Underscore.js - http://underscorejs.org/#bind
transport.on('data', _.bind(function () { alert(this.data); }, this));
function MyConstructor(data, transport) {
var self = this;
this.data = data;
transport.on('data', function() {
alert(self.data);
});
}
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => {
alert(this.data);
});
}
P粉9680081752023-10-12 00:55:03
此内容您应该了解
this
(aka "konteks") ialah kata kunci khas dalam setiap fungsi yang nilainya bergantung hanya pada bagaimana fungsi dipanggil, bukan bagaimana/bila/di mana ia ditakrifkan. Ia tidak dipengaruhi oleh skop leksikal seperti pembolehubah lain (kecuali fungsi anak panah, lihat di bawah). Berikut adalah beberapa contoh:
function foo() { console.log(this); } // normal function call foo(); // `this` will refer to `window` // as object method var obj = {bar: foo}; obj.bar(); // `this` will refer to `obj` // as constructor function new foo(); // `this` will refer to an object that inherits from `foo.prototype`
Untuk mengetahui lebih lanjut tentang 此
, lihat dokumentasi MDN.
this
ECMAScript 6 memperkenalkan fungsi anak panah, yang boleh dianggap sebagai fungsi lambda. Mereka tidak mempunyai this
绑定。相反,this
就像普通变量一样在范围内查找。这意味着您不必调用 .bind
mengikat mereka sendiri. Sebaliknya,
.bind
. Ini bukan satu-satunya tingkah laku istimewa mereka, lihat dokumentasi MDN untuk mendapatkan maklumat lanjut. function MyConstructor(data, transport) { this.data = data; transport.on('data', () => alert(this.data)); }
这个
Jangan guna
this
,而是访问它引用的对象。这就是为什么一个简单的解决方案是简单地创建一个也引用该对象的新变量。变量可以有任何名称,但常见的是 self
和 that
Anda sebenarnya tidak mahu mengakses
akses objek yang dirujuknya self
是一个普通变量,因此它遵循词法范围规则并且可以在回调内部访问。这还有一个优点,即您可以访问回调本身的 this
. Itulah sebabnya penyelesaian mudah adalah dengan hanya mencipta pembolehubah baharu yang juga merujuk 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
ialah pembolehubah biasa, ia mengikut peraturan skop leksikal dan boleh diakses di dalam panggilan balik. Ini juga mempunyai kelebihan iaitu anda boleh mengakses nilai this
panggilan balik itu sendiri. Menetapkan panggilan balik secara eksplisit this
- Bahagian 1
Nampaknya anda tidak mempunyai kawalan ke atas nilai kerana nilainya ditetapkan secara automatik, tetapi sebenarnya tidak begitu. .bind
[docs],它返回一个新函数,其中 this
绑定到一个值。该函数与您调用 .bind
的函数具有完全相同的行为,只是 this
是由您设置的。无论何时或如何调用该函数,this
this
绑定到 MyConstructor
的 this
this
- Bahagian 2Sesetengah fungsi/kaedah yang menerima panggilan balik juga menerima nilai yang this
应该引用的值。这与您自己绑定它基本上相同,但是函数/方法会为您完成它。 Array#map
harus dirujuk oleh panggilan balik. Ini pada asasnya sama seperti mengikatnya sendiri, tetapi fungsi/kaedah melakukannya untuk anda. Array#map
< em> [docs]Ini kaedahnya. Tandatangannya ialah:
array.map(callback[, thisArg])
Parameter pertama ialah panggilan balik dan parameter kedua ialah nilai this
harus 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); // <- here we are passing `obj` as second argument
Nota: Sama ada boleh menghantar nilai untuk this
传递值通常在该函数/方法的文档中提到。例如, jQuery 的 $.ajax
方法 [docs] 描述了一个名为 context
biasanya disebut dalam dokumentasi fungsi/kaedah tersebut. Contohnya, kaedah $.ajax
jQuery
Soalan Lazim: Menggunakan kaedah objek sebagai panggilan balik/pengendali acara
Satu lagi manifestasi biasa masalah ini ialah apabila kaedah objek digunakan sebagai pengendali panggilan balik/event. Fungsi ialah warga kelas pertama dalam JavaScript, dan istilah "kaedah" hanyalah istilah sehari-hari untuk fungsi, yang merupakan nilai harta objek. Tetapi fungsi itu tidak mempunyai pautan khusus kepada objek "mengandungi"nya. this.method
被指定为点击事件处理程序,但如果点击document.body
,记录的值将是未定义
,因为在事件处理程序中,this
引用的是 document.body
,而不是 Foo
Pertimbangkan contoh berikut: this
function Foo() { this.data = 42, document.body.onclick = this.method; } Foo.prototype.method = function() { console.log(this.data); };Fungsi
this.method
ditentukan sebagai pengendali acara klik, tetapi jika document.body
diklik, nilai yang dilog akan menjadi undefined
kerana Dalam pengendali acara, merujuk kepada document.body
, bukan contoh Foo
.
Seperti yang telah disebutkan di awal, apa yang merujuk bergantung pada bagaimana fungsi ditakrifkan .
Mungkin lebih jelas bahawa fungsi itu tidak mempunyai rujukan tersirat kepada objek jika kod kelihatan seperti ini: .bind
将this
function method() { console.log(this.data); } function Foo() { this.data = 42, document.body.onclick = this.method; } Foo.prototype.method = method;
Penyelesaian this
adalah sama seperti yang dinyatakan di atas: gunakan .bind
untuk mengikat secara eksplisit
jika tersedia
document.body.onclick = this.method.bind(this);Atau panggil fungsi secara eksplisit sebagai "kaedah" objek dengan menggunakan fungsi tanpa nama sebagai pengendali panggilan balik/peristiwa dan tetapkan objek (🎜) kepada pembolehubah lain: 🎜
var self = this; document.body.onclick = function() { self.method(); };🎜atau gunakan fungsi anak panah: 🎜
document.body.onclick = () => this.method();