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 thisiç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ı selfve that.
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
Yana selfnormal bir değişkendir, bu sözcük kapsam kuralları uyar ve geri arama içeride erişilebilir. Bu ayrıca thisgeri arama değerine erişebilme avantajına sahiptir .
Açıkça thisgeri arama seti - Bölüm 1
thisDeğ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 thissizin 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, thisher 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 thisdeğerine MyConstructorbağ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 thisbağları yok. Bunun yerine, thisnormal 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));
}
thisGeri arama seti - bölüm 2
Geri aramaları kabul eden bazı işlevler / yöntemler de geri aramaların thisbaş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 thisbaş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 thisiletip iletemeyeceğiniz genellikle bu işlevin / yöntemin belgelerinde belirtilir. Örneğin, jQuery'nin $.ajaxyö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.bodytıklanırsa, undefinedolay işleyicisi içinde örneğini değil, günlüğe thisatı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.bodyFoo
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 .bindaçıkça bağlanmak thisiç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();