Bir JavaScript dosyasında gördüm:
function Somefunction(){
var that = this;
...
}
Bunu beyan that
ve atamanın amacı nedir this
?
Bir JavaScript dosyasında gördüm:
function Somefunction(){
var that = this;
...
}
Bunu beyan that
ve 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ü this
yeni 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 that
asıl değerine erişmenizi sağlar this
.
Şahsen, that
takma 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 that
değ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
that
değişkenin örneğinde hiç kullanılmamasıdır. Bir değişken tutma oluşturmak this
kodun 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 this
otomatik olarak genel kapsama ayarlanır. this
Dış 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 this
nesneye işaret eder (bu durumda car
) bir yöntemdir, ancak iç işlevde this
artı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ı that
kullanı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ı that
Eğ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 this
baş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 this
oluş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 sayHi
dan yöntemle that
bu yüzden, DOM çağrısı içinde sorunsuz çağrılabilir.
Başka bir çözüm, boş bir that
nesne 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.