Использование методов экземпляра в качестве обратных вызовов для обработчиков событий изменяет область действия this из «Мой экземпляр» «Независимо от того, что только что вызвало обратный вызов» . Мой код выглядит следующим образом:

function MyObject() {
  this.doSomething = function() {
    ...
  }

  var self = this
  $('#foobar').bind('click', function(){
    self.doSomethng()
    // this.doSomething() would not work here
  })
}

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

Этот вопрос относится не только к jQuery, но и к JavaScript в целом. Основная проблема заключается в том, как «направить» переменную во встроенные функции. Вот пример:

var abc = 1; // we want to use this variable in embedded functions

function xyz(){
  console.log(abc); // it is available here!
  function qwe(){
    console.log(abc); // it is available here too!
  }
  ...
};

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

// we want to use "this" variable in embedded functions

function xyz(){
  // "this" is different here!
  console.log(this); // not what we wanted!
  function qwe(){
    // "this" is different here too!
    console.log(this); // not what we wanted!
  }
  ...
};

Что мы можем сделать? Присвойте его некоторой переменной и используйте его через псевдоним:

var abc = this; // we want to use this variable in embedded functions

function xyz(){
  // "this" is different here! --- but we don't care!
  console.log(abc); // now it is the right object!
  function qwe(){
    // "this" is different here too! --- but we don't care!
    console.log(abc); // it is the right object here too!
  }
  ...
};

this не является уникальным в этом отношении: arguments является другой псевдопеременной, которая должна обрабатываться таким же образом — с помощью псевдонимов.

Да, похоже, это общий стандарт. Некоторые кодеры используют себя, другие используют меня. Он используется как ссылка на «реальный» объект, а не на событие.

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

Обычно я делаю это прямо в верхней части моего объекта (извините за демонстрационный код — он более концептуален, чем все остальное и не является уроком о превосходной технике кодирования):

function MyObject(){
  var me = this;

  //Events
  Click = onClick; //Allows user to override onClick event with their own

  //Event Handlers
  onClick = function(args){
    me.MyProperty = args; //Reference me, referencing this refers to onClick
    ...
    //Do other stuff
  }
}
var functionX = function() {
  var self = this;
  var functionY = function(y) {
    // If we call "this" in here, we get a reference to functionY,
    // but if we call "self" (defined earlier), we get a reference to function X.
  }
}

edit: несмотря на вложенные функции внутри объект принимает глобальный объект окна, а не окружающий объект.

Если вы используете ES2015 или скрипт типа и ES5, то вы можете использовать функции стрелок в своем коде, и вы не столкнетесь с этой ошибкой, и это относится к желаемой области действия в вашем экземпляре.

this.name = 'test'
myObject.doSomething(data => {
  console.log(this.name)  // this should print out 'test'
});

Одним из решений этой проблемы является привязка всего вашего обратного вызова к вашему объекту с помощью метода bind javascript.

Вы можете сделать это с помощью именованного метода,

function MyNamedMethod() {
  // You can now call methods on "this" here 
}

doCallBack(MyNamedMethod.bind(this)); 

Или с помощью анонимного обратного вызова.

doCallBack(function () {
  // You can now call methods on "this" here
}.bind(this));

Выполнение этого вместо обращения к var self = this показывает, как вы понимаете привязку this ведет себя в javascript и не использует ссылку на закрытие.

. Кроме того, оператор толстой стрелки в ES6 в основном это то же самое, что вызов .bind(this) для анонимной функции:

doCallback( () => {
  // You can reference "this" here now
});

Я не использовал jQuery, но в такой библиотеке, как Prototype, вы можете привязать функции к определенной области видимости. Таким образом, с учетом этого ваш код будет выглядеть следующим образом:

 $('#foobar').ready('click', this.doSomething.bind(this));

Метод bind возвращает новую функцию, которая вызывает оригинальный метод с указанной вами областью действия.

Я думаю, что на самом деле это зависит от того, что вы собираетесь делать внутри своей функции doSomething. Если вы собираетесь получить доступ к свойствам MyObject по этому ключевому слову, вы должны использовать это. Но я думаю, что следующий фрагмент кода также будет работать, если вы не делаете каких-либо специальных действий, используя свойства object(MyObject).

function doSomething(){
  .........
}

$("#foobar").ready('click', function(){

});

Просто добавьте к этому, что в ES6 из-за Функции стрелок просто, чтобы прояснить для простых умов, подобных моему (из this.