Что лежит в основе этой идиомы JavaScript: var self = this?

Я видел следующее в источнике для WebKit HTML 5 SQL хранения отмечает демо:

function Note() {
  var self = this;

  var note = document.createElement('div');
  note.className = 'note';
  note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
  note.addEventListener('click', function() { return self.onNoteClick() }, false);
  this.note = note;
  // ...
}

автор использует self в некоторых местах (тело функции) и этой в других местах (тела функций, заданных в списке аргументов метода). Что происходит? Теперь, когда я заметил это однажды, я начну видеть это повсюду?

10 ответов


посмотреть этот статья о alistapart.com

self используется для поддержания ссылки на оригинал this даже при изменении контекста. Это метод, часто используемый в обработчиках событий (особенно в закрытиях).


Я думаю, что имя переменной "self" больше не должно использоваться таким образом, поскольку современные браузеры предоставляют глобальная переменная self указывает на глобальный объект обычного окна или веб-пользователя.

чтобы избежать путаницы и потенциальных конфликтов, вы можете написать var thiz = this или var that = this вместо.


Да, вы увидите его повсюду. Это часто that = this;.

видел, как self используется внутри функций, вызываемых событиями? У них был бы свой собственный контекст, так что self до this, вступившего в Note().

причина self по-прежнему доступен для функций, хотя они могут выполняться только после Note() функция закончила выполнять, что внутренние функции получают контекст внешней функции из-за закрытие.


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

как функция может быть вызвана с заданным контекстом с помощью function.apply или function.call, вы можете написать оболочку, которая возвращает функцию, которая вызывает вашу функцию с apply или call используя данный контекст. Увидеть в jQuery proxy функция для реализации этого шаблона. Вот пример используя его:

var wrappedFunc = $.proxy(this.myFunc, this);

wrappedFunc затем можно вызвать и будет иметь вашу версию this в зависимости от контекста.


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


это причуда JavaScript. Когда функция является свойством объекта, более метко называемым методом,этой относится к объекту. В Примере обработчика событий содержащим объектом является элемент, который инициировал событие. Когда вызывается стандартная функция, этой будет ссылаться на глобальный объект. Когда у вас есть вложенные функции, как в вашем примере, этой не относится к контексту внешней функции вообще. Внутренние функции делят область с содержащей функцией, поэтому разработчики будут использовать вариации var that = this для того, чтобы сохранить этой они нуждаются во внутренней функции.


как пояснил var self = this; позволяет код закрытие вернуться к родительской области.

однако теперь 2018 и ES6 широко поддерживаются всеми основными веб-браузерами. The var self = this; идиома не так важна, как когда-то.

теперь можно избежать var self = this; С помощью функции стрелочку.

в случаях, когда мы бы использовали var self = this:

function test() {
    var self = this;
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", function() {
        console.log(self.hello); // logs "world"
    });
};

теперь мы можем использовать функцию стрелки без var self = this:

function test() {
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", () => {
        console.log(this.hello); // logs "world"
    });
};

функции стрелки не имеют своих собственных this и просто предположить видимости.


на самом деле self является ссылкой на окно (window.self), поэтому когда вы говорите var self = 'something' вы переопределяете ссылку окна на себя-потому что self существует в объекте окна.

вот почему большинство разработчиков предпочитают var that = this над var self = this;

в любом случае;var that = this; не соответствует хорошей практике ... предполагая, что ваш код будет пересмотрен / изменен позже другими разработчиками, вы должны использовать наиболее распространенные стандарты программирования в отношении сообщества разработчиков

поэтому вы должны использовать что-то вроде var oldThis / var oThis / etc-чтобы быть ясным в вашей области / / ..не так много, но сэкономит несколько секунд и несколько циклов мозга


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


function Person(firstname, lastname) {
  this.firstname = firstname;

  this.lastname = lastname;
  this.getfullname = function () {
    return `${this.firstname}   ${this.lastname}`;
  };

  let that = this;
  this.sayHi = function() {
    console.log(`i am this , ${this.firstname}`);
    console.log(`i am that , ${that.firstname}`);
  };
}

let thisss = new Person('thatbetty', 'thatzhao');

let thatt = {firstname: 'thisbetty', lastname: 'thiszhao'};

thisss.это очень просто.call (thatt);