Что означает 'var that = this;' в JavaScript?



в файле JavaScript я увидел:



function Somefunction(){
var that = this;
...
}


какова цель объявления that и назначении его this?

519   6  

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 Спецификация, которая вызывает этой будет неверно задано для внутренних функций.

JS Fiddle

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

    Ничего не найдено.