У файлі JavaScript я побачив:
function Somefunction(){
var that = this;
...
}
Яка мета декларування thatта присвоєння thisцього?
У файлі JavaScript я побачив:
function Somefunction(){
var that = this;
...
}
Яка мета декларування thatта присвоєння thisцього?
Відповіді:
Почну цю відповідь із ілюстрації:
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
});
});
Моя відповідь спочатку продемонструвала це за допомогою jQuery, який лише трохи відрізняється:
$('#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
});
});
Тому що this часто змінюється, коли ви змінюєте область, викликаючи нову функцію, ви не можете отримати доступ до вихідного значення, використовуючи його. Псевдонім це thatдозволяє ще отримувати доступ до початкового значення this.
Особисто мені не подобається використання thatпсевдоніма. Рідко буває очевидно, про що йдеться, особливо якщо функції довші пари ліній. Я завжди використовую більш описовий псевдонім. У своїх вище прикладах я б, мабуть, використовував clickedEl.
var self = this;. Слово , thatздається, має на увазі змінну нічого АЛЕ this.
forEachФункція приймає другий необов'язковий аргумент , який є зв'язування функції. colours.forEach(function(){/* 'this' is bound correctly --> */}, this);Тому слід додати примітку, var that = thisяка насправді не потрібна forEach.
За умовою ми робимо приватну цю змінну. Це використовується, щоб об'єкт став доступним приватним методам. Це тимчасове рішення для помилки в специфікації ECMAScript мови , який викликає це повинен бути встановлений неправильно для внутрішніх функцій.
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);
Це сповіщення ...
ВикористанняТа думає, що це називається Дейв
ВикористанняЦе вважає, що це називається невизначеним
thatзмінна взагалі не використовується в його прикладі. Це робить його схожим на те, що просто створення змінної холдингу thisщось робить для решти коду.
Це злом, щоб внутрішні функції (функції, визначені всередині інших функцій) працювали так, як повинні. У JavaScript, коли ви визначаєте одну функцію всередині іншої, thisавтоматично встановлюється глобальна область. Це може бути заплутано, тому що ви очікуєте thisмати те саме значення, що і у зовнішній функції.
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();
};
Це конкретно проблема, коли ви створюєте функцію як метод об'єкта (як car.startу прикладі), а потім створюєте функцію всередині цього методу (як activateStarter). У методі верхнього рівня thisвказує на об'єкт, це метод (в даному випадку car), але у внутрішній функціїthis тепер вказує на глобальну сферу. Це біль.
Створення змінної для використання за умовчанням в обох областях - це рішення цієї дуже загальної проблеми з javascript (хоча це корисно і у функціях jquery). Ось чому саме загальна звучала назваthat . Це легко впізнавана умова подолання недоліку в мові.
Як Ель Ронноко натякає на Дугласа Крокфорда, вважає, що це гарна ідея.
Використання thatнасправді не є необхідним, якщо ви вирішите рішення із використанням call()або 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);
};
Іноді thisможна посилатися на іншу область і посилатися на щось інше, наприклад, припустимо, ви хочете викликати метод конструктора всередині події DOM, в цьому випадкуthis буде посилатися на елемент DOM, а не на створений об'єкт.
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
Рішення вище волі Ассінга thisдля thatцього ми можемо і доступ до властивості імені всередині sayHiметоду зthat , так що це може бути викликано без проблем всередині виклику DOM.
Інше рішення - призначити порожній thatоб’єкт і додати до нього властивості та методи, а потім повернути його. Але з цим рішенням ви втратили prototypeконструктор.
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};
Ось приклад `
$(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();
}
});
}
});
});`
Таким чином, ви можете бачити, що це значення є двома різними значеннями залежно від елемента DOM, на який ви націлюєтесь, але коли ви додаєте "що" до коду вище, ви змінюєте значення "this", на яке орієнтуєтесь.
`$(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 ("фон-колір", "# ffe700"); // Тут значення "що" є ".our-work-group> p> a", оскільки значення var що = це; тому, навіть якщо ми знаходимося на "this" = '.our-work-one-page', ми все одно можемо використовувати "that" для маніпулювання попереднім елементом DOM.