6 ответов:
Я собираюсь начать этот ответ с иллюстрацией:
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.
С Крокфорд
по соглашению, мы делаем частный это переменная. Это используется, чтобы сделать объект, доступный для частного лица методы. Это делается для ошибка в языке 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);этого уведомления...
UsesThat думает, что это называется Дэйв
UsesThis думает, что это называется undefined
это хак, чтобы сделать внутренние функции (функции, определенные внутри других функций) больше работают, как они должны. В 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не требуется, если вы делаете обходной путь с использованием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решение выше будет assing
thisдоthatтогда мы можем и получить доступ к свойству name внутри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(); } }); } }); });`таким образом, вы можете видеть, что значение this-это два разных значения в зависимости от целевого элемента DOM, но когда вы добавляете "это" в код выше, вы меняете значение "это", на которое вы нацеливаетесь.
`$(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(); } }); } }); });`.....$(что).css ("background-color", "#ffe700"); //здесь значение "что" является ".our-work-group > p > a "потому что значение var that = this; поэтому, хотя мы находимся в "этом"= '.our-work-single-page', все же мы можем использовать "это" для управления предыдущим элементом DOM.
Comments