Должен ли я ссылаться на «это» в локальной переменной? - PullRequest
4 голосов
/ 07 марта 2012

Я часто вижу это в коде: var me = this;. Это почему? Есть ли какой-то выигрыш в производительности, если я ссылаюсь на 'this' в локальной переменной?

Ответы [ 8 ]

9 голосов
/ 07 марта 2012

Это полезно, если есть функции внутри функции, так что код в этих вложенных функциях должен иметь доступ к значению this из внешнего контекста.

function example() {
  var me = this;
  document.getElementById('whatever').onclick = function() {
    me.clicked = 1;
  };
}

Поскольку this устанавливается заново для каждого вызова функции, без сохранения внешней this в переменной не было бы никакой возможности ссылаться на нее из внутренней функции.

4 голосов
/ 07 марта 2012

Используется для сохранения ссылки на this.Позже в коде есть вызов AJAX с обратным вызовом (например).Таким образом, внутри этого обратного вызова this не то же самое, что снаружи.Вот почему люди копируют «внешнюю» this в переменную.

Лично мне нравится использовать эту форму:

var that = this;

выглядит смешно:)

ПоКстати, CoffeeScript , который является своего рода «правильным JavaScript», также исправляет это.

Он имеет две формы для определения функции, тонкую стрелку и жирную стрелку.Тонкая стрелка ведет себя точно так же, как в javascript, а толстая стрелка автоматически связывает this со значением из внешнего контекста.

Итак, этот кофейный скрипт

Account = (customer, cart) -> # thin arrow
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) => # fat arrow
    @customer.purchase @cart

преобразуется в этот JavaScript

var Account;
Account = function(customer, cart) {
  var _this = this;
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', function(event) {
    return _this.customer.purchase(_this.cart);
  });
};

Круто, не правда ли?

1 голос
/ 07 марта 2012

Обычная причина в том, что код содержит замыкание, которое будет вызвано через некоторое время, и автор хочет убедиться, что закрытие имеет доступ к текущему this. Пример:

Вот код, который люди часто пишут неправильно, например:

var obj = {
    name: "Fred",
    foo: function() {
        setTimeout(function() {
            alert(this.name); // <=== Fails, `this` is no longer `obj`
        }, 1000);
    }
};
obj.foo();

Вот что var me = this; применено к нему:

var obj = {
    name: "Fred",
    foo: function() {
        var me = this;
        setTimeout(function() {
            alert(me.name); // <=== Works now
        }, 1000);
    }
};
obj.foo();

Это происходит потому, что в JavaScript this полностью определяется как функция называется , а не там, где определена функция.

Подробнее (раскрытие: обе ссылки на мой блог) :

1 голос
/ 07 марта 2012

Это часто используется для методов обратного вызова, где область действия будет отличаться при выполнении обратного вызова.

Пример:

var me = this;
$.getJSON(url, function(data) {
  // here "this" will be "window", so "me" is used to access the object
})
1 голос
/ 07 марта 2012

IMO, это необычно, вы сами увидите это - это конструкция, почти всегда используемая, когда есть замыкания, чтобы избежать обработки JS значения this, вычисляемого во время выполнения, а не объявления.

1 голос
/ 07 марта 2012

Это так, что когда this изменяется, у вас все еще есть ссылка на this в той точке кода, которая вам нужна.

0 голосов
/ 29 июля 2017

Используется с внутренними функциями.Как вы знаете, у вас могут быть функции в конструкторах объектов, а внутри функций могут быть функции.Если вы видите код ниже.

function Circle(radius){
this.radius=radius;
this.getArea=function(){
                    var changeRadius=function(){
                            this.radius=20; //here this points to global
                        }
                    changeRadius();
                    return Math.PI*Math.pow(this.radius, 2);
                    }
}

var cd= new Circle(10);
console.log(cd.getArea());

Когда вы вызываете getArea (), вы получите область в соответствии с радиусом 10. Хотя вы вызываете changeRadius (), но внутри внутренней функции changeRadius, она начинает указывать наглобальный объект вместо объекта, который вы создали.Вы используете var self=this construct, чтобы обойти это.

, поэтому, чтобы обойти эту ситуацию, мы можем внести следующие изменения.

function Circle(radius){
var self=this;
this.radius=radius;
this.getArea=function(){
                    var changeRadius=function(){
                            self.radius=20;
                        }
                    changeRadius();
                    return Math.PI*Math.pow(this.radius, 2);
                    }
}

var cd= new Circle(10);
console.log(cd.getArea());
0 голосов
/ 07 марта 2012

Это для объема закрытия.Посмотрите на разницу в этих двух плагинах jQuery:

$.fn.blinkClosure = function() {
    var jQueryMonad = this, toggleClass = this.toggleClass;
    setInterval(function() {
        toggleClass.apply(jQueryMonad, ['invisible']);
    }, 500);
};

Проблема с setInterval.Когда вызывается функция в setInterval, она запускает новую цепочку выполнения, и this в этой цепочке связывается с window.В примере закрытия мы сохраняем ссылку на объект jQuery, к которому мы применяем плагин, в jQueryMonad (или me в вашем коде).Таким образом, мы можем сохранить нашу область видимости правильной в javascript.

$.fn.blink = function() {
    setInterval($.proxy(function() {
        this.toggleClass('invisible');
    }, this), 500);
};

Во втором примере jQuery.proxy обрабатывает это для вас.

Это для решения проблем, когда javascript связывается1016 * во время выполнения, а не во время создания.

...