Настала пора мысленно вернуться на четыре с небольшим года назад ко блогозаписи «
Simple “Class” Instantiation» из блога Джона Резига, прославленного создателя необыкновенно удобной библиотеки jQuery. И вернёмся.
Однако же, так как я вовсе не вижу её
в результатах поиска на Хабрахабре по слову «Resig», то поневоле приходится думать, что эту полезную блогозапись никто не удосужился перевести (или хотя бы пересказать) за четыре прошедших года — мне придётся, стало быть, самостоятельно пересказать блогозапись Резига прежде, чем я исполню моё главное намерение: поразмыслить вслух, почему же предложенный Резигом способ решения указанной им проблемы так и не сделался общераспространённым. И перескажу. (Сам этот пересказ ужé был бы полезен читателю, даже кабы я к нему ничего от себя не прибавил. А я прибавлю.)
Шестого декабря 2007 года Резиг рассмотрел, что получается, когда в джаваскрипте используется операция «new» для создания объекта (в языках с классами мы сказали бы «экземпляра класса»):
function User(first, last){
this.name = first + " " + last;
}
var user = new User("John", "Resig");
Резиг справедливо подметил, что для начинающих программистов на джаваскрипте не вполне очевидно, что появление «this» в коде функции указывает на то, что перед нами конструктор объекта. (Я от себя в скобках прибавлю: если функция находится в недрах некоторой библиотеки, то это обстоятельство нуждается также и в документировании — а не то пользователь библиотеки не многим будет отличаться от новичка: исходный код с телом функции читают не все, тем более что он нередко применяется в минифицированном, не читаемом виде.)
Поэтому, рассудил Резиг, рано или поздно
кто-нибудь попробует вызвать «
User()»
без «new» и тем получит на свою голову сразу две неприятные проблемы.
Во-первых, переменная «
user» останется неопределённою: функция «
User()» задумана ведь как конструктор, а значения она никакого не возвращает.
Во-вторых, что ещё хуже, попытки обращения
к «this» изнутри такого (некорректно вызванного) конструктора неизбежно приведёт к засорению глобального пространства имён — а это чревато зловещими и трудноуловимыми последствиями. Обе проблемы Джон Резиг продемонстрировал на примере:
var name = "Resig";
var user = User("John", name);
// здесь переменная «user» не определена
// БОЛЕЕ ТОГО: значение «name» теперь ужé не «Resig»!
if ( name == "John Resig" ) {
// фигассе!…
}