cari

Rumah  >  Soal Jawab  >  teks badan

Bagaimana untuk mengakses "ini" yang betul dalam panggilan balik

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粉296080076P粉296080076410 hari yang lalu564

membalas semua(2)saya akan balas

  • P粉311423594

    P粉3114235942023-10-12 09:02:51

    Berikut ialah beberapa cara untuk mengakses konteks ibu bapa dalam konteks kanak-kanak -
    1. Anda boleh menggunakan fungsi 绑定().
    2. Simpan rujukan kepada konteks/ini dalam pembolehubah lain (lihat contoh di bawah).
    3. Menggunakan fungsi ES6 anak panah.
    4. Tukar kod, reka bentuk berfungsi dan seni bina - untuk ini anda harus menguasai Corak Reka Bentuk dalam JavaScript.

    1.Gunakan bind()fungsi

    function 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));

    2 Simpan rujukan kepada 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);
      });
    }
    

    balas
    0
  • P粉968008175

    P粉9680081752023-10-12 00:55:03

    Mengenai此内容您应该了解

    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.


    Cara petik yang betulthis

    Gunakan fungsi anak panah

    ECMAScript 6 memperkenalkan fungsi anak panah, yang boleh dianggap sebagai fungsi lambda. Mereka tidak mempunyai this 绑定。相反,this 就像普通变量一样在范围内查找。这意味着您不必调用 .bind mengikat mereka sendiri. Sebaliknya,

    dilihat dalam skop sama seperti pembolehubah biasa. Ini bermakna anda tidak perlu memanggil .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,而是访问它引用的对象。这就是为什么一个简单的解决方案是简单地创建一个也引用该对象的新变量。变量可以有任何名称,但常见的是 selfthatAnda sebenarnya tidak mahu mengakses

    secara khusus, tetapi

    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);
        });
    }

    Memandangkan 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

    Setiap fungsi mempunyai kaedah

    .bind this 绑定到 MyConstructorthis

    [docs]

    , yang mengembalikan fungsi baharu dengan terikat pada nilai. Fungsi ini mempunyai gelagat yang sama seperti fungsi yang anda panggil .bind, kecuali jQuery .proxy ditetapkan oleh anda. Tidak kira bila atau bagaimana fungsi dipanggil, akan sentiasa merujuk kepada nilai yang diluluskan.

    function MyConstructor(data, transport) {
        this.data = data;
        var boundFunction = (function() { // parenthesis are not necessary
            alert(this.data);             // but might improve readability
        }).bind(this); // <- here we are calling `.bind()` 
        transport.on('data', boundFunction);
    }
    Dalam contoh ini, kami mengikat panggilan balik kepada nilai MyConstructor's .

    🎜🎜Nota: 🎜Apabila mengikat konteks ke jQuery, gunakan 🎜🎜 🎜🎜[docs]🎜🎜🎜 sebaliknya. Sebab untuk ini adalah supaya anda tidak perlu menyimpan rujukan kepada fungsi apabila membatalkan ikatan panggilan balik acara. jQuery mengendalikan ini secara dalaman. 🎜

    Menyediakan panggilan balik this - Bahagian 2

    Sesetengah 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

    [docs]

    menerangkan pilihan yang dipanggil konteks:

    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
    dipanggil

    , bukan bagaimana

    ditakrifkan . Mungkin lebih jelas bahawa fungsi itu tidak mempunyai rujukan tersirat kepada objek jika kod kelihatan seperti ini: .bindthis

    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

    kepada nilai tertentu

    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();

    balas
    0
  • Batalbalas