С момента добавления конструкторов классов в ES6 в последнее время javascript получил много плохих отзывов в прессе. Изучая их использование, я наткнулся на десятки статей, в которых жаловалось, что они просто «синтаксический сахар» (модное новое модное словечко) или что они просто метод наименования объектов или просто беспорядок вся парадигма ООП.
Конечно, когда вы видите, что кого-то задирают, ваш первый инстинкт - пойти вперед и защитить маленького парня. Итак, вот немного о нашем опыте работы с классами и конструкторами.
Вот пример, который мы использовали:
// Создаем класс для CrewMember
class CrewMember {
конструктор (имя, работа, specialSkill) {
this.name = имя;
this.job = работа;
this.specialSkill = specialSkill;
this.ship = null;
} // Убедитесь, что члены экипажа могут заходить на корабли
enterShip (корабль) {this.ship = ship;
ship.crew.push (это); }
} // Создаем класс для корабля
class Ship {
конструктор (имя, тип, способность) {
this.name = имя;
this.type = тип;
this.ability = способность;
this.crew = [];
} // Убедитесь, что вернули заявление о миссии
missionStatement () {
if (this.crew.length === 0) {
return «Пока не могу выполнить задание»;
} еще верните this.ability;
}
}
Это было все упражнение. Конечно, это сработало так, как было указано, потому что спецификации не были слишком сложными.
Боковой анекдот: когда они сменили руководство на фабрике, на которой я работал, новый начальник однажды сказал мне, что хочет, чтобы я удалил все поля индекса из каждой записи в каждой таблице моей базы данных SQL Server с более чем 1000000 записей. Заметьте, это было в компании из списка Fortune 50 - и я не ошибся в написании «500», на самом деле это было число 48. Почему он проповедовал такое безумие? Потому что все эти индексы «тратили пространство для хранения на сервере».
Причина, по которой я стараюсь указать на это, заключается в том, что в какой-то момент вашей карьеры вам, вероятно, скажут выполнить какую-то операцию, которую вы, с точки зрения «в коде», можете сказать, что она должна быть проделана другим способом. Но начальник, с его точки зрения: «Я главный, делай, что говорю», столь же непреклонен.
Дала ли я этому молодому менеджеру то, что он требовал? Нет. К тому времени я уже мог сказать, в какую сторону дует ветер. Именно тогда я понял, что вся программа смены руководства заключалась в том, чтобы просто разрушить это место и вести себя так, как будто это был несчастный случай.
Поэтому, когда они предложили извечному ультиматуму «если ты не сможешь этого сделать, мы найдем того, кто сможет», я просто радостно ушел на пенсию, взял пенсию и провел год, катаясь в траве и цыплятах. Он точно показал мне. И - предупреждение о спойлере - они так и не нашли того «того, кто может».
Этот завод просуществовал чуть меньше 4 лет после того, как эти люди пришли к власти. Они даже не могли разрушить это место правильно. Но в конце концов они все еще использовали мое программное обеспечение, и все записи базы данных имели свои счастливые маленькие индексные поля.
Я хочу сказать, что каждая новая вещь кажется глупой тому, кто уже делал что-то определенным образом раньше.
Для того, чтобы объектно-ориентированное программирование было успешным, ребята, работающие «сверху вниз», должны были потерпеть полный провал. Потому что он определенно делал вещи не так, как мы всегда.
Итак, теперь самое главное - Closure vs Scope. Я не претендую на звание программиста - я то, что вы называете художником-программистом. Я не собираюсь сидеть сложа руки и обсуждать синтаксические нюансы, когда я мог бы просто писать код. Что, кажется, работает для меня, потому что эта компания все еще использовала мое программное обеспечение - не тронутое мной - три года спустя, когда завод закрылся.
Вот демонстрация Closure vs Scope. Его предоставили прекрасные ребята из freecodecamp:
var v = 1;
var f1 = function () {
console.log(v);
}
var f2 = function() {
var v = 2;
f1(); // Will this print 1 or 2?
};
f2();
Как вы думаете, что напечатает приведенный выше пример? Код прост:
f1()
выводит значениеv
, которое равно 1 в глобальной области видимости, но мы выполняемf1()
внутриf2()
, у которого другойv
, равный 2. Затем мы выполняемf2()
.
Будет ли этот код печатать 1 или 2?
Если вы захотите сказать 2, вы удивитесь. Этот код фактически напечатает 1. Причина в том, что области действия и закрытия разные. Строка
console.log
будет использовать закрытиеf1()
, которое создается, когда мы определяемf1()
, что означает, что закрытиеf1()
дает нам доступ только к областиf1()
плюс глобальная область. Область, в которой мы выполняемf1()
, не влияет на это закрытие. Фактически, закрытиеf1()
вообще не даст нам доступа к областиf2()
. Если вы удалите глобальную переменнуюv
и выполните этот код, вы получите справочную ошибку:
var f1 = function () {
console.log(v);
}
var f2 = function() {
var v = 2;
f1(); // ReferenceError: v is not defined
};
f2();
Теперь вы, как специализированный художник по программному обеспечению, вероятно, никогда бы не использовали код, подобный приведенному в приведенных выше примерах. Это явное проявление того, что я называю «безудержным» стилем разработки кода.
Дело в том, что есть люди, которые пишут код, и есть люди, которые пишут статьи о коде. Пусть они повеселятся, они никому не причинят вреда (кроме, может быть, неустойчивого нового ученика, который еще не может четко различать академиков и приложений).
Вы можете написать миллион строк кода и никогда не нарушать закрытие. Или вы можете написать десять и столкнуться с этим в первый же день. Что, честно говоря, более вероятно. Приятно знать, что кто-то сосредоточен на абстракциях всего этого.
Это возвращает меня к «классу» в javascript.
Я использовал структуру классов из этого задания, чтобы сделать свою собственную классную ретро-текстовую игру под названием Mission To Mars. Моим первым подходом было бы прямое ООП, но выполнение его с использованием предоставленных мне спецификаций дало мне часы удовольствия и несколько интересных идей:
- Когда вы встраиваете массивы или объекты в структуру классов, анализировать их становится особым кошмаром.
EX: Вот как вы циклически просматриваете все звездные базы и перечисляете их свойства и атрибуты, когда одно из них является массивом свойств, а одно из свойств - массивом элементов, которые они несут:
for (let i = 0; i ‹Base.objects.length; i ++) {
for (введите Base.objects [i]) {
if (typeof Base.objects [i] [key] === ’object’) {
let objArray = Base.objects [i] [key];
if (! objArray.length) {
textHTML + = «Товар для продажи:« + objArray.name + »- Стоимость:« + objArray.cost + »- Примечания:« + objArray.saleText + «‹br/›»;
} еще {
for (let x = 0; x ‹objArray.length; x ++) {
textHTML + = «Предмет для продажи:« + objArray [x] .name + »- Стоимость:« + objArray [x] .cost + »- Примечания:« + objArray [x] .saleText + «‹br/›»;
}
}
} else textHTML + = key + «:« + Base.objects [i] [key] + «‹br/›»;
} textHTML + = «‹br/› - - - - - - - - - - - - ‹br/›»;
} textHTML + = «‹br/›»;
- Чтобы ссылаться на коллекцию объектов из одного и того же класса, вы должны поддерживать массив этих объектов внутри класса. Тогда становится легче. Этот пример - это «проще, мягче».
- Дополнительный уровень абстракции обеспечивает дополнительный уровень сложности для предоставления результатов. Не невозможно, но и не интуитивно.
Это похоже на художника по программному обеспечению внутри вас. Я не знаю, знал ли Пикассо в первую очередь о насыщенности или оттенках, но я также не знаю, есть ли работы людей, которые пишут научные статьи, обсуждая их нюансы, в Лувре?
Я просто боюсь, что дело доходит до того, что когда два программиста говорят о коде, это все равно, что находиться в комнате, полной экономистов, обсуждающих экономику, или священников, обсуждающих тонкости религии.
Как этот другой пример из нашего задания: «Можете ли вы предложить вариант использования нового синтаксиса функции стрелки =>
? Чем этот новый синтаксис отличается от старой сигнатуры функции function nameFunc(){}
как по стилю, так и по функциональности? »
Вот как:
Пожалуй, Mozilla.org говорит об этом лучше всего:
Выражение функции стрелки является синтаксически компактной альтернативой регулярному выражению функции, хотя и без собственной привязки к ключевым словам
this
,arguments
,super
илиnew.target
. Выражения стрелочных функций плохо подходят в качестве методов и не могут использоваться в качестве конструкторов.