Instantly share code, notes, and snippets.

@subzey /readme.md
Last active Dec 6, 2017

Embed
What would you like to do?
Про это

Про это

Как вы называете переменную, когда нужно сохранить this в замыкании?

Вопрос не праздный, ведь это дело даже не личного вкуса, а, скорее, договоренности. В коде проекта, над которым я сейчас активно работаю, можно было с равной степенью вероятности встретить that и self. Через два года разработки, впрочем, баланс заметно сместился в сторону that.

Но знаете, что? И self, и that, и даже _this с me — это очень хреновые названия.

Почему?

Представим скрипт, который срывает ягоды тутовника (такие маленькие и сильно пачкаются). Делаем все круто и объектно-ориентированно:

function MulberryPlucker() {}
MulberryPlucker.prototype.pluckedMulberry = null;
MulberryPlucker.prototype.pluck = function() {
	var that = this;
	var asyncPlucker = new AsyncPlucker('mulberry');
	asyncPlucker.pluck(function(mulberry) {
		that.pluckedMulberry = mulberry;
	});
}

Вы можете сказать, это такое? В смысле, что означает that? Пока что да, хорошо, а так?

function MulberryPlucker() {}
MulberryPlucker.prototype.pluckedMulberry = null;
MulberryPlucker.prototype.pluck = function() {
	var that = this;
	AsyncPluckerAsyncFactory.createPlucker(function(asyncPlucker) {
		asyncPlucker.onreadystatechange = function() {
			if (asyncPlucker.readyState === asyncPlucker.STATE_READY) {
				asyncPlucker.pluck(function(mulberry) {
					if (typeof GlobalNotifier !== 'undefined'){
						GlobalNotifier.notifyNewMulberry(mulberry);
					}
					that.pluckedMulberry = mulberry;
				});
			}
		}
		asyncPlucker.setTypeAsync('mulberry');
	})
}

Уже сложнее. А если добавить ещё десяток уровней вложенности и кода экрана два? Или так: в рабочий чатик прилетает сообщение, мол, а что делает эта функция?

function(mulberry) {
	that.pluckedMulberry = mulberry;
}

Вы сможете ответить точно и сразу?

Увы, это реальность, код не находится в кристально чистом состоянии, и не всегда код, который мы поддерживаем — это код, который мы писали. И чтобы как-то сгладить эффекты этой самой реальности мы, программисты, называем переменные понятными именами. Так почему же, чёрт возьми, не делать то же самое с this.

А как же?

А очень просто. Точно так же, как конструктор, только с маленькой буквы. Т.е., если this представляет собой инстанс EvilDestructionWidget, то его имеет смысл обозвать evilDestructionWidget.

И код чудесным образом становится более понятным:

function MulberryPlucker() {}
MulberryPlucker.prototype.pluckedMulberry = null;
MulberryPlucker.prototype.pluck = function() {
	var mulberryPlucker = this;
	var asyncPlucker = new AsyncPlucker('mulberry');
	asyncPlucker.pluck(function(mulberry) {
		mulberryPlucker.pluckedMulberry = mulberry;
	});
}

Ну, разве не красота?

Но…

Что, даже в микроскопическом методе?

Да. Везде. Это всегда так, «ой, у меня всего-лишь маленький скриптик, пусть всё будет валяться в глобале…», и чем это заканчивается?

Это же увеличит размер js-файла

А вы разве не минифицируете скрипты? Очень советую. Тем более, что такие переменные обычно не «торчат» наружу и прекрасно переименовываются минификатором во что-нибудь однобуквенное.

Ладно… мне просто лениво печатать.

Я вас умоляю. Вы знаете, как работает this, что такое замыкание, и пишете код в notepad.exe? Наверняка ваш редактор умеет делать подстановку.

Имя конструктора и так начинается с маленькой буквы

А зря. Переименуйте везде на большую и не позорьтесь.

Мой конструктор называется That

Ладно, тогда можно. Но вы в курсе, это отвратительное имя для конструктора.

@ptmt

This comment has been minimized.

ptmt commented May 24, 2015

В 2015 как минимум:

class MulberryPlucker {
   constructor() {
       this.pluckedMulberry = null
   }
   pluck() {
      let asyncPlucker = new AsyncPlucker('mulberry')
      asyncPlucker.pluck(mulberry => this.pluckedMulberry = mulberry)
   }
}
@felixexter

This comment has been minimized.

felixexter commented May 24, 2015

Долгое время использовали _this, но этот гист заставил задуматься и стандартизировать это 😄

@kinday

This comment has been minimized.

kinday commented May 24, 2015

@felixexter, привет. (:

Красиво и понятно, я за стандартизацию.

@listochkin

This comment has been minimized.

listochkin commented May 24, 2015

Мне кажется, что идея не самая лучшая.

  1. Программисты ожидают, что эта переменная будет называться self, that или _this. Некоторые стайлгайды даже закрепляют одно из этих названий. Видеть незнакомую переменную в такой роли будет запутывать других разработчиков.

  2. Практика подобных названий закрепилась во времена, когда в браузерах по умолчанию не было родной реализации Function.prototype.bind. Сегодня, когда она у нас есть, лучшее название для this - это this:

    doSomething(function (param, pamPam) {
      this.doSomethinElse(pamPam);
    }.bind(this));
  3. С ES6, который при помощи транспайлеров можно смело использовать уже несколько лет как, проблема решается еще проще, как выше показал @unknownexception

@VovanR

This comment has been minimized.

VovanR commented May 24, 2015

Надо будет попробовать на новом небольшом проекте, чтобы понять насколько это может быть неудобно для команды.
Так, например, во всяких сниппетах, шаблонах и скафолдерах уже забито _this.

@AveVlad

This comment has been minimized.

AveVlad commented May 24, 2015

revised this gist on 25 Dec 2013
а щас 2015 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment