Нашел еще один JavaScript-фреймворк (спасибо Виктору за наводку), который на несколько порядков быстрее всех остальных. Прошу любить и жаловать vanilla.js! Если верить создателям, то получение всех элементов по имени тега отрабатывает быстрее jQuery в 425 раз. Я думаю, одного этого достаточно, чтобы глянуть на фреймворк.
Вы, наверное, слышали об этом JavaScript-фреймворке. Модный тренд, если позволите так выразиться. Superheroic JavaScript MVW1 Framework, как утвержают сами разработчики. Не удержался и посмотрел на него, тем более что выдалась возможность сделать это в рабочее время и за счет заказчика. Мы выбираем основу для будущего проекта, вот и решили глянуть современные js фреймворки, и мне достался AngularJS. Поделюсь своими впечатлениями.
Не знаю как с производительностью, но с функциональностью у этого фреймворка полный порядок. Покажу на небольшом примере. Итак, у нас есть кусочек разметки:
<table class="table table-striped table-hover" ng-controller="TestController">
<thead>
<tr>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="action in actions">
<td>{{action.action}}</td>
</tr>
</tbody>
</table>
Дальше мы подключаем JavaScript:
function TestController($scope) {
$scope.actions = [
{action: 'Action1'},
{action: 'Action2'}
];
}
Ну и всё. У нас готова страница с таблицей, в которой 2 строки: «Action1» и «Action2». Но это еще не все. Если мы потом добавим в поле actions
еще чего-нибудь, то оно тоже автоматически отобразится на странице.
Единственное, мне потребовалось некоторое время, чтобы разобраться с некоторыми более сложными вещами. Например, создание независимых компонентов. В моей задаче требовалось, чтобы родительский компонент передавал данные для дочернего. В результате оказалось, что на момент вызова родительского контроллера дочерний еще не инициализирован и нужно немного подождать. И лучше всего использовать для этого событие $viewContentLoaded
. Чтобы это понять, официального сайта было недостаточно, и пришлось провести пару-тройку часов в обнимку с дебаггером и гуглом.
В общем, впечатление от фреймворка очень положительное, надо будет попробовать написать что-нибудь более-менее серьезное.
Еще примеры можете оценить на главной странице фреймворка, они там гораздо лучше, чем я вам привел.
Model-View-Whatever
JavaScript прекрасен. Но в нем есть некоторое количество так называемых особенностей, которые делают его чуть менее прекрасным, чем хотелось бы. Например, приведение типов.
[]+[]
> ""
[]+{}
> "[object Object]"
{}+[]
> 0
{}+{}
> NaN
Почему так? Это кажется бредом, пока не разберешься с системой типов в JavaScript. Ладно-ладно, это кажется бредом в любом случае, но тем не менее попробуем хоть чуть разобраться.
Самое главное, что нужно знать — операция +
работает только с примитивными типами. Т.е. что бы вы ни написали, выражение будет приведено к этим типам. Даже больше: если хотя бы один операнд — строка, то и результат будет строкой. Поэтому, чтобы понять причину происходящего выше, нужно узнать, как объекты и массивы приводятся к примитивным типам.
У каждого объекта и массива (ведь массив тоже объект) есть 2 метода: valueOf
и toString
. И именно они будут использоваться для преобразования типов. Сначала интерпретатор вызывает valueOf
, и если он вернул не примитивное значение, то вызывается toString
. Теперь нужно выяснить, что же возвращают эти методы у {}
и []
.
console.log({}.valueOf()); // Возвращает себя
console.log([].valueOf()); // [] (тоже себя)
console.log([].toString()); // ""
console.log({}.toString()); // "[object Object]"
Засада. Каким образом {}+[]
дает 0, ведь по логике должно быть "[object Object]"
? Ковыряние в спецификации пока ни к чему не привело. Если кто знает правильный ответ, не томите, поделитесь наблюдениями.
Ну и совсем напоследок видео, из-за которого я начал разбираться в этой теме. Посмотрите, не пожалеете.
UPD: Исправлен верхний листинг.
UPD2: Разгадка.
Блог подвергся тотальной оптимизации. Теперь всё должно работать еще быстрее и еще лучше. Теперь на каждой странице осталось только по одному js и css файлу, конечно, если не считать сторонние сервисы — Disqus и Google Analytics. И вообще везде царствует гармония и фен-шуй.
Весь javascript был переписан с использованием Google Closurе. Попутно в него были внесены мелкие, но приятные дополнения. Например, навигация с помощью комбинаций клавиш Ctrl+← и Ctrl+→ или эмуляция переходов между состояниями (transitions) для старых браузеров, не поддерживающих CSS Transitions. Конечно, для этого пришлось написать часть кода из плагинов Twitter Bootstrap. Но в любом случае я доволен: суммарный размер всех js фалов на рабочем сервере уменьшился в 3 раза: со 180 до 60 килобайт. Да и прокачанный навык в Google Closure многого стоит.
С CSS было проще: я просто выкинул неиспользуемые части из Twitter Bootstrap и добавил свой код в результирующий файл. Это не заняло много времени.
А еще теперь при наведении на стоку в листинге с кодом слева подписывается ее номер. Не особо нужная штука, но может кому пригодиться.
Весь код, как обычно, на GitHub, включая новые большие скрипты для сборки проекта. Смотрим, изучаем, комментируем.
Был замечен сегодня утром.