Dojo Toolkit это одновременно самый мощный и наименее используемый JavaScript фреймворк. В то время, как почти каждый JavaScript фреймворк или тулкит обещает сделать все на свете и даже больше, Dojo Toolkit предоставляет наиболее убедительные аргументы в доказательство своей функциональности. В этом посте будут описаны многие важные возможности Dojo Toolkit, а также будет рассказано, почему вы должны использовать его в своем следующем проекте.
понедельник, 12 августа 2013 г.
четверг, 20 июня 2013 г.
Быстрое переключение на любой рабочий стол
четверг, 16 мая 2013 г.
Головоломный JavaScript
Головоломный JavaScript¶
Время от времени в сети мне попадаются различные WTF примеры на JavaScript. Часто на первый взгляд они выглядят безумно, но на самом деле просты и логичны, поэтому я решил попробовать их собирать и разбирать. Кроме очевидного профита в виде более глубого понимаю языка это еще и отличные вопросы для собеседований)
Чтобы было интереснее я буду прятать ответ и решение под спойлер.
1. Так что помните, дети, всегда подставляем системы счисления!¶
Для начала простой, но прикольной пример. Что вернут такие вызовы parseInt?
parseInt('fuck');
parseInt('fuck', 16);
parseInt('fuck'); // NaN
parseInt('fuck', 16); // 15
Как работает parseInt: он посимвольно проверяет переданную строку на соответствие указанной вторым аргументом системе счисления и если находит некорректный символ, то завершает работу. По умолчанию, система счисления считается десятичной, при условии, что переданная строка не начинается с 0. В десятичной системе счисления символ ‘f’ недопустим и функция заканчивается свою работу не найдя ни одной цифры. А вот в шестнадцатиричной системе символ ‘f’ допустим и соответствует десятичному числу 15. Символ ‘u’ не допустим и функция завершает свою работу.
2. Может кто подскажет?¶
Чему равно такое выражение?
"Why am I a " + typeof + "";
“Who am I a number”
Оператор “+” обладает большим приоритетом чем “typeof”, поэтому указанная запись эквивалентна следующей:
“Why am I a ” + (typeof (+ “”)).
Унарный “+”” выполняет привидение к числу, поэтому “typeof” от результата его выполнения - это number.
3. Кто больше?¶
Ну и кто больше?
[1, 2, 4] < [1, 2, 5]
[1, 2, 'd'] < [1, 2, 5]
[1, 2, ['d', 5]] < [1, 2, [20, 5]]
[1, 2, 5] == [1, 2, 5]
[1, 2, 5] <= [1, 2, 5]
[1, 2, 5] >= [1, 2, 5]
[1, 2, 4] < [1, 2, 5] //true
[1, 2, 'd'] < [1, 2, 5] //false
[1, 2, ['d', 5]] < [1, 2, [20, 5]] //false
[1, 2, 5] == [1, 2, 5] //true
[1, 2, 5] <= [1, 2, 5] //true
[1, 2, 5] >= [1, 2, 5] //true
Согласно спецификации ECMAScript 5 для выполнения операции сравнения аргументы, которые не являются примитивами, должны быть привидены к примитивам (если кому интересно, то пункт 11.8.5 “Алгоритм сравнения абстрактного отношения”). Сначала JavaScript пробует преобразовать аргумент к числу с помощью метода valueOf и только когда это не удается приводит к строковому типу (изначально я хотел написать здесь про естественность сравнения чисел, и что когда мы говорим, что слово А больше слова Б, то имеем в виду длину. Но из беседы с коллегой выяснилось, что это не правда. Когда мы сравнимаем два слова мы инстанцируем связанные с ними образы и сравнимаем их. И только если образов не нашлось, то сравниваем слова не как метки образов, а именно как набор букв). Для массивов метод valueOf не определен и поэтому они сравниваются как строки:
"1,2,4" < "1,2,5" //true
"1,2,d" < "1,2,5" //false
Но все вышесказаное верно только для операций сравнения. В случае оператора “==”” привидение к примтивам осуществляется только если один из аргументов примитив, а во всех остальных случаях оператор “==” возвращает true только если оба аргумента ссылаются на один объект (пункт 11.9.3 “Алгоритм сравнения абстрактного равенства”), что в нашем случае не так.
Следует заметить, что для объектов сравнение работать не будет, т.к. их дефолтный toString возвращает [object Object].
Ладно, объекты сравнивать нельзя, но почему бы не проверять массивы на равенство с помощью сравнения? Все пишут циклы, а ведь можно обойтись одной строкой:
!(arr1 < arr2)&&!(arr1 > arr2)
Что-то подсказывает, что постоянные игры с привидением типов должны очень сильно отъедать время и ресурсы. Сделаем небольшой наколеночный тест:
var arr1 = [],
arr2 = [],
res,
start,
end,
len = 600000;
for(var i=0; i<len; i++){
arr1[i] = i;
arr2[i] = i;
// if(i == len-100) arr2[i] = i+1; //чтобы делать не равные массивы
}
//проверим, что массивы создались
console.log(arr1.length, arr2.length);
//наш метода
start = new Date();
res = !(arr1 < arr2)&&!(arr1 > arr2);
end = new Date();
console.log(end.getTime() - start.getTime(), res);
//классический циклический
start = new Date();
for(var i=0; i<len; i++)
res &= (arr1[i] === arr2[i]);
end = new Date();
console.log(end.getTime() - start.getTime());
Разница поражает: 123мс на 2015мс в пользу привидения типов!
Несмотря на это я не советую использовать такой метод, т.к. при попадании в массив объектов он начнет врать, кроме того, он использует не самое очевидное поведение языка.
понедельник, 15 апреля 2013 г.
GNOME Shell Extensions
вторник, 26 февраля 2013 г.
В начале был narod...
- что-нибудь интересное по JavaScript;
- личные открытия в общении с openSUSE;
- про незаслуженно заигноренный на просторах нашей Родины js-фреймворк Dojo
