Bilmeniz gerekenler this
this
(diğer bir deyişle "bağlam") her bir işlevin içindeki özel bir anahtar kelimedir ve değeri , işlevin nasıl / ne zaman / nerede tanımlandığına değil, yalnızca işlevin nasıl çağrıldığına bağlıdır . Diğer değişkenler gibi sözcüksel kapsamlardan etkilenmez (ok işlevleri hariç, aşağıya bakın). İş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`
Hakkında daha fazla bilgi edinmek this
için MDN belgelerine bakın .
Doğru nasıl başvurulur this
Kullanma this
Aslında this
özel olarak erişmek istemezsiniz , ama sözünü ettiği nesne . Bu nedenle kolay bir çözüm, o nesneyi de ifade eden yeni bir değişken oluşturmaktır. Değişkenin herhangi bir adı olabilir, ancak yaygın olanları self
ve that
.
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
Yana self
normal bir değişkendir, bu sözcük kapsam kuralları uyar ve geri arama içeride erişilebilir. Bu ayrıca this
geri arama değerine erişebilme avantajına sahiptir .
Açıkça this
geri arama seti - Bölüm 1
this
Değeri otomatik olarak ayarlandığından, değeri üzerinde hiçbir kontrolünüz yok gibi görünebilir , ancak aslında durum böyle değildir.
Her işlev, bir değere bağlı yeni bir işlev döndüren .bind
[docs] yöntemine sahiptir this
. İşlev .bind
, yalnızca this
sizin tarafınızdan ayarlanmış olanla aynı davranışa sahiptir . Bu işlev nasıl veya ne zaman çağrılırsa çağrılsın, this
her zaman iletilen değere işaret eder.
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 aramaları 's this
değerine MyConstructor
bağlarız this
.
Not: jQuery için bağlam bağlarken, bunun yerine jQuery.proxy
[docs] kullanın. Bunu yapmanın nedeni, bir olay geri aramasını bağlarken işleve başvuruyu depolamanıza gerek kalmamasıdır. jQuery bunu dahili olarak ele alır.
ECMAScript 6 , lambda işlevleri olarak düşünülebilecek ok işlevlerini sunar. Kendi this
bağları yok. Bunun yerine, this
normal bir değişken gibi kapsam olarak bakılır. Bu, aramak zorunda olmadığınız anlamına gelir .bind
. Sahip oldukları tek özel davranış bu değildir, daha fazla bilgi için lütfen MDN belgelerine bakın.
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => alert(this.data));
}
this
Geri arama seti - bölüm 2
Geri aramaları kabul eden bazı işlevler / yöntemler de geri aramaların this
başvurması gereken bir değeri kabul eder. Bu temel olarak kendiniz bağlamakla aynıdır, ancak işlev / yöntem bunu sizin için yapar. Array#map
[dokümanlar] böyle bir yöntemdir. İmzası:
array.map(callback[, thisArg])
İlk argüman geri arama, ikinci argüman ise değerin this
başvurması gerektiğidir. İşte örnek 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: Bir değer this
iletip iletemeyeceğiniz genellikle bu işlevin / yöntemin belgelerinde belirtilir. Örneğin, jQuery'nin $.ajax
yöntemi [docs] , şu şekilde adlandırılan bir seçeneği açıklar context
:
Bu nesne, Ajax ile ilgili tüm geri çağrıların bağlamı haline getirilecektir.
Genel sorun: Nesne yöntemlerini geri çağrılar / olay işleyicileri olarak kullanma
Bu sorunun ortak bir başka belirtisi, bir nesne yönteminin geri çağrı / olay işleyicisi olarak kullanılmasıdır. İşlevler, JavaScript'teki birinci sınıf vatandaşlardır ve "yöntem" terimi, bir nesne özelliğinin değeri olan bir işlev için yalnızca konuşma dilidir. Ancak bu işlevin "içeren" nesnesine belirli bir bağlantısı yoktur.
Aşağıdaki örneği düşünün:
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = function() {
console.log(this.data);
};
İşlev this.method
, click olay işleyicisi olarak atanır, ancak document.body
tıklanırsa, undefined
olay işleyicisi içinde örneğini değil, günlüğe this
atıfta bulunduğu için günlüğe kaydedilen değer olur .
Başlangıçta daha önce de belirtildiği gibi, ne ifade edileceği, işlevin nasıl tanımlandığına değil, nasıl adlandırıldığına bağlıdır .
Kod aşağıdaki gibiyse, işlevin nesneye örtülü bir başvurusu olmadığı daha açık olabilir:document.body
Foo
this
function method() {
console.log(this.data);
}
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = method;
Çözüm , yukarıda belirtilenle aynıdır: Varsa, belirli bir değere .bind
açıkça bağlanmak this
için kullanın
document.body.onclick = this.method.bind(this);
veya geri arama / olay işleyici olarak anonim bir işlev kullanarak işlevi nesnenin "yöntemi" olarak açıkça çağırır ve object ( this
) öğesini başka bir değişkene atar :
var self = this;
document.body.onclick = function() {
self.method();
};
veya bir ok işlevi kullanın:
document.body.onclick = () => this.method();