Bir JavaScript dosyasında gördüm:
function Somefunction(){
var that = this;
...
}
Bunu beyan thatve atamanın amacı nedir this?
Bir JavaScript dosyasında gördüm:
function Somefunction(){
var that = this;
...
}
Bunu beyan thatve atamanın amacı nedir this?
Yanıtlar:
Bu cevaba bir örnekle başlayacağım:
var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
// this is a reference to the element clicked on
var that = this;
colours.forEach(function() {
// this is undefined
// that is a reference to the element clicked on
});
});
Cevabım bunu aslında çok az farklı olan jQuery ile gösterdi:
$('#element').click(function(){
// this is a reference to the element clicked on
var that = this;
$('.elements').each(function(){
// this is a reference to the current element in the loop
// that is still a reference to the element clicked on
});
});
Çünkü thisyeni bir işlevini çağırarak kapsamını değiştirmek zaman sık sık değişir, bunu kullanarak özgün değeri erişemez. İçin diğer adının thatasıl değerine erişmenizi sağlar this.
Şahsen, thattakma ad olarak kullanılmasından hoşlanmıyorum . Özellikle işlevler birkaç satırdan daha uzunsa, neye atıfta bulunduğu nadiren açıktır. Her zaman daha açıklayıcı bir takma ad kullanırım. Yukarıdaki örneklerimde muhtemelen kullanırım clickedEl.
var self = this;. Kelime thatdeğişkeni bir şey var gibi görünüyor AMA this.
forEachİşlev, bağlanması olan bir ikinci isteğe bağlı bir argümandır alır. colours.forEach(function(){/* 'this' is bound correctly --> */}, this);Dolayısıyla var that = this, aslında gerekli olmayan bir not eklenmelidir forEach.
Gönderen Crockford
Geleneksel olarak, bu değişkeni özel yapıyoruz . Bu, nesneyi özel yöntemlerin kullanımına sunmak için kullanılır. Bu neden ECMAScript Dil Şartnamede bir hata için geçici bir çözümdür bu iç fonksiyonlar için yanlış ayarlanmış olması.
function usesThis(name) {
this.myName = name;
function returnMe() {
return this; //scope is lost because of the inner function
}
return {
returnMe : returnMe
}
}
function usesThat(name) {
var that = this;
this.myName = name;
function returnMe() {
return that; //scope is baked in with 'that' to the "class"
}
return {
returnMe : returnMe
}
}
var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
"UsesThis thinks it's called " + usesthis.returnMe().myName);
Bu uyarılar ...
Dave dendiğini düşünen
Bu, tanımsız olarak adlandırıldığını düşünüyor
thatdeğişkenin örneğinde hiç kullanılmamasıdır. Bir değişken tutma oluşturmak thiskodun geri kalanına bir şey yapıyormuş gibi görünmesini sağlar .
Bu, iç işlevlerin (diğer işlevlerde tanımlanan işlevler) olması gerektiği gibi çalışmasını sağlamak için bir hack'tir. Javascript içinde bir işlevi tanımladığınızda başka bir işlev thisotomatik olarak genel kapsama ayarlanır. thisDış işlevde olduğu gibi aynı değere sahip olmayı beklediğiniz için bu kafa karıştırıcı olabilir .
var car = {};
car.starter = {};
car.start = function(){
var that = this;
// you can access car.starter inside this method with 'this'
this.starter.active = false;
var activateStarter = function(){
// 'this' now points to the global scope
// 'this.starter' is undefined, so we use 'that' instead.
that.starter.active = true;
// you could also use car.starter, but using 'that' gives
// us more consistency and flexibility
};
activateStarter();
};
Bu, özellikle bir nesnenin yöntemi olarak bir işlev oluşturduğunuzda ( car.startörnekte olduğu gibi activateStarter) ve bu yöntemin içinde (örneğin) bir işlev oluşturduğunuzda bir sorundur . Üst düzey yöntemde thisnesneye işaret eder (bu durumda car) bir yöntemdir, ancak iç işlevde thisartık küresel kapsamı göstermektedir. Bu bir acı.
Her iki kapsamda da kural olarak kullanılacak bir değişken oluşturmak, javascript ile ilgili bu çok genel soruna bir çözümdür (jquery işlevlerinde de yararlıdır). Bu yüzden genel ses adı thatkullanılır. Dilde bir eksikliğin üstesinden gelmek için kolayca tanınabilir bir konvansiyon.
El Ronnoco gibi Douglas Crockford'un ipuçları bunun iyi bir fikir olduğunu düşünüyor.
Kullanılması thatEğer kullanımı ile geçici bir çözüm yaparsanız gerçekten gerekli değildir call()ya apply():
var car = {};
car.starter = {};
car.start = function(){
this.starter.active = false;
var activateStarter = function(){
// 'this' now points to our main object
this.starter.active = true;
};
activateStarter.apply(this);
};
Bazen thisbaşka bir kapsama başvurabilir ve başka bir şeye başvurabilir, örneğin bir DOM olayı içindeki bir yapıcı yöntemini çağırmak istediğinizi varsayalım, bu durumda thisoluşturulan nesneye değil DOM öğesine atıfta bulunun.
HTML
<button id="button">Alert Name</button>
JS
var Person = function(name) {
this.name = name;
var that = this;
this.sayHi = function() {
alert(that.name);
};
};
var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad
Yukarıdaki çözüm this,that daha sonra biz ve iç erişim ismi özelliğini sayHidan yöntemle thatbu yüzden, DOM çağrısı içinde sorunsuz çağrılabilir.
Başka bir çözüm, boş bir thatnesne atamak ve ona özellikler ve yöntemler eklemek ve sonra geri döndürmektir. Ancak bu çözümle kurucuyu kaybettiniz prototype.
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};
İşte bir örnek `
$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();
var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
var imgAlt = $(this).find('img').attr('alt'); //Here value of "this" is '.our-work-single-page'.
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}
});
});`
Böylece, bu değerin, hedeflediğiniz DOM öğesine bağlı olarak iki farklı değer olduğunu görebilirsiniz, ancak yukarıdaki koda "o" eklediğinizde, hedeflediğiniz "bu" değerinin değerini değiştirirsiniz.
`$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();
var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
var that = this;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
***$(that).css("background-color", "#ffe700");*** //Here value of "that" is ".our-work-group > p > a"....
var imgAlt = $(this).find('img').attr('alt');
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}
});
});`
..... $ (that) .css ("arka plan rengi", "# ffe700"); // Burada "that" değeri ".our-work-group> p> a" olur, çünkü var değeri = this; "this" = '.our-work-single-page "konumunda olmamıza rağmen, yine de önceki DOM öğesini değiştirmek için" that "komutunu kullanabiliriz.