SORU
29 Kasım 2013, Cuma


Nasıl doğru erişim için `` / bu içeriği geri arama içinde?

Bir olay işleyicisi kaydeden yapıcı bir işlevi var:

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

Ancak geri içinde oluşturulan nesneyi data özelliği erişmek için güçlü değilim. this ama bir diğeri için oluşturulan nesneyi ifade etmez gibi görünüyor.

Ben de bir anonim fonksiyon yerine bir nesne yöntemi kullanmaya çalıştı:

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

MyConstructor.prototype.alert = function() {
    alert(this.name);
};

ama bu sergiler aynı sorunlar.

Nasıl doğru nesneyi erişebilir miyim?

CEVAP
29 Kasım 2013, Cuma


Ne this hakkında

this ("içerik") her bir işlev içinde özel bir kelime olduğunu ve değerini sadece bağlıdır . aka ^em>nasıltanımlı olduğu fonksiyon çağrıldı, nasıl//. Sözlü kapsamı, diğer değişkenler gibi etkilenmez. İşte bazı örnekler:

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`

Daha fazla this, hakkında bilgi edinmek için MDN documentation bakabilirsiniz.


Doğru bakın nasıl 23**

this kullanmayın

Aslında özellikle this erişim istemiyorum amaanlamına gelir nesne. Bu kolay bir çözüm sadece, aynı zamanda o nesnenin başvurduğu yeni bir değişken oluşturmak için. Değişken herhangi bir ad olabilir, ama ortak olanlar self that.

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

self normal bir değişken olduğu için, sözlü kapsam kurallara itaat eder ve geri arama içinde erişilebilir.

Açıkça ayarlanmış geri arama this - bölüm 1

Değeri otomatik olarak ayarlandığından this değeri üzerinde hiçbir kontrole sahip gibi görünebilir, ama aslında durum böyle değil.

Her fonksiyonu yöntemi vardır this ile yeni bir fonksiyon değerine bağlı döner .bind [docs],. İşlevi tam olarak .bind denilen this tarafından kuruldu aynı davranış vardır. Bu işlevi ne olursa olsun, this her zaman geçti değerine bakın.

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

Bu durumda, geri arama this MyConstructordeğeri'40 *s*. bağlama ediyoruz

Not:Bir WordPress kullanmak için bağlam bağlama, jQuery.proxy [docs] kullanın. Bunun nedeni, geri arama olay kesmeden işlev başvurusu, mağaza gerek yok. jQuery bu dahili olarak işler.

ECMA 6: arrow functions

ECMA 6 tanıtırok işlevlerilambda fonksiyonları olarak düşünülebilir., this kendi bağlayıcılığı yok. , 43* *normal bir değişken gibi kapsamı içinde aranacağı yerine. .bind aramak zorunda kalmazsınız. Onlar, lütfen daha fazla bilgi için MDN belgelerine sahip bakın sadece özel bir davranış değil.

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

Geri arama this - bölüm 2 ayarlayın

Geri aramaları kabul eden yöntemleri/bazı fonksiyonları da geri arama this bakmalıdır bir değer kabul eder. Bu temelde kendini bağlayıcı olarak aynı ama işlev/yöntem sizin için yapıyor. Array#map [docs] böyle bir yöntemdir. İmza:

array.map(callback[, thisArg])

İlk argüman geri ve ikinci bağımsız değişken this bakmalıdır değerdir. Burada yapmacık bir örnek:

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

Not:Ya iletebilirsiniz olup olmadığını this için bir değer genellikle bir işlev/yöntem belgelerinde belirtilir. Örnek context: bir seçenek açıklar

Bu nesne Ajax ile ilgili tüm kapsamında geri verilecek.


Ortak sorun: geri çağrıları Kullanarak nesne yöntemleri / olay işleyicileri

Bu sorunu başka bir ortak tezahürü nesne bir geri arama yöntemi olarak kullanılan olay işleyicisi. Fonksiyonlar JavaScript birinci sınıf vatandaş ve "yöntem" sadece bir nesne özellik değeri bir işlev için argo bir terimdir. terim vardır Ama bu işlev için özel bir bağlantı "" nesne. içeren yok

Düşünün aşağıdaki örnek:

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

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

İşlevi this.method atanan tıklatın olay işleyicisi, ama eğer vücudun tıklandığında, oturum değeri olacak undefined, çünkü içinde olay işleyicisi, this ifade eder vücut, örneğin Foo.
Zaten başında da belirtildiği gibi, this ne ifade eder işlevini bağlıdıraradınasıl olduğunu değil., ^strong>tanımlanmış.
Eğer kodu aşağıdaki gibi olsaydı, işlevi örtülü bir referans yok daha bariz nesne olabilir:

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


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

Foo.prototype.method = method;

Çözümmevcut, açıkça belirli bir değere this bağlamak .bind kullanın . Eğer yukarıda belirtildiği gibi aynıdır:

document.body.onclick = this.method.bind(this);

ya da açıkça bir "nesne, isimsiz bir fonksiyon kullanarak geri arama / olay ve nesne (this) başka bir değişken için işleyici atamak: . yöntem olarak işlevini çağırın

var self = this;
document.body.onclick = function() {
    self.method();
};

ya da bir ok fonksiyonu kullanın:

document.body.onclick = () => this.method();

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • KIT KAT

    KIT KAT

    3 EKİM 2005
  • TeachMeComputer

    TeachMeCompu

    31 EKİM 2009
  • ThisWeekYT

    ThisWeekYT

    14 Mart 2013