На этой неделе мы продолжили изучение более фундаментальных концепций программирования на Javascript и изучили такие темы, как наследование объектов, ajax-запросы и рекурсия с печально известной проблемой n-ферзей. Я действительно начал приспосабливаться к временным затратам программы и обнаружил, что легче, чем ожидалось, иметь достаточно энергии для эффективного усвоения материала. Курс движется быстро, но пока не слишком быстро, чтобы мы не успевали. Вот пара отличных вещей, которые я узнал на этой неделе.

Object.create против нового

Вероятно, это тема, которая заслуживает отдельного поста, если не отдельной электронной книги. Я никогда не был на 100% уверен в том, в чем разница между ними. Я в основном использовал ключевое слово new и никогда не удосужился узнать, когда использовать Object.create при настройке прототипов. Вот пример, когда это уместно:

SmartPhone.prototype = Object.create(Phone.prototype);
SmartPhone.prototype.constructor = SmartPhone;

Допустим, вы пытаетесь создать объект SmartPhone, который является подклассом класса Phone. Это типичное связывание прототипов, которые мы используем в псевдоклассической реализации. Есть ли разница, чем когда мы связываем их вот так?

SmartPhone.prototype = new Phone();
SmartPhone.prototype.constructor = SmartPhone;

С удивлением узнал, что действительно есть. Основное отличие состоит в том, что ключевое слово new создает объект this, вызывает конструктор и возвращает созданный объект this. Это может быть проблематично, если, например, конструктор полагается на переданные параметры, а мы не передаем никаких. Поэтому, когда мы не хотим на самом деле запускать функцию-конструктор, а просто хотим связать прототипы, лучше ли использовать Object.create.

N-Королевы

Вторая интересная проблема, с которой я столкнулся на этой неделе, связана с печально известной проблемой n ферзей. Вас просят написать алгоритм для решения всех решений того, как разместить n стандартных шахматных ферзей на доске N x N. Мой партнер и я смогли сделать это с помощью рекурсивного алгоритма, но обнаружили, что наш алгоритм работает довольно медленно при расчетах с более высокими значениями N.

Этот спринт научил нас многому о рекурсии и временной сложности. Большую часть второго дня мы сосредоточились на оптимизации и ускорении нашего алгоритма. Наш самый большой прорыв произошел, когда мы проанализировали вспомогательные функции, которые использовали, и поняли, что они делают ненужные проверки атак ферзя. Когда мы устранили их, наш код мгновенно ускорился в 20 раз. Упрощение рекурсивного кода, который обычно имеет квадратичную временную сложность, дает огромную отдачу. Это хорошо иметь в виду при написании рекурсивных алгоритмов в будущем.