Подлипенский Павел

Блог о технологиях и деньгах

Думаете, вы знаете JavaScript

clock апреля 28, 2009 06:30 by author Подлипенский Павел

Вы бородатый веб разработчик и думаете уже видали всякие чудеса в JavaScript-коде? Хм, чтож тогда следующие задачки для вас. 

1. ++Math.PI
2. (0.1 + 0.2) + 0.3 == 0.1 + (0.2 + 0.3)
3. typeof NaN
4. typeof typeof undefined
5. a = {null:null}; typeof a.null;
6. a = "5"; b = "2"; c = a * b;
7. a = "5"; b = 2; c = a+++b;
8. isNaN(1/null)
9. (16).toString(16)
10. 016 * 2
11. ~null
12. "ab c".match(/\b\w\b/)

Жду ваши варианты в комментариях (просьба не постить по десять одинаковых комментариев, все равно раньше чем я их промодерю они не появятся). До компа я доберусь только завтра, поэтому и ваши комментарии тоже появятся только завтра, а заодно и обновление к этому посту - в виде ответов и объяснений к решениям (да, я их сопру с ваших комментариев, поэтому сначала думайте, а потом пишите!) 

Ответы и решения:

1. 4.141592653589793

С этим надеюсь понятно, в школе все учились.... Я знаю некоторых смутило, что Пи вроде как должно быть константой, но спешу вас разочаровать - в джаваскрипте с константами плохо, а точнее их нет в том понимании, в каком мы видим их, скажем, в C#.

2. false

Такой же ответ получат и Java разработчики, потому как и Java и JavaScript используют IEEE 754 числа с плавающей точкой. Более подробно об операциях с числами с плавающей точкой можно найти тутаньки 

3. "number"

Логического объяснения этому я не нашел, единственное что могу посоветовать, это стараться использовать isNaN вместо typeof SomePotentialNumber, во избежание казусов. 

4. "string" 

Тут все просто - первый оператор typeof вернет тип переменной в виде строки, следовательно второй оператор должен вернуть тип результата первого оператора, т.е. string. 

5. "object"

Мы присвоили переменной а, объект с полем "null", значение которого null, а это в свою очередь, пусть и специфический, но объект. Другими словами мы тут имеем a.null === null.

6. 10

Если в операциях умножение, деление или вычитание один из операторов строка - интерпретатор пытается преобразовать его в число.

7. 7

Порядок выполнения операндов в Javascript  идет слева направо, поэтому мы имеем "а увеличить на 1, а затем сложить с b". 

8. false

С этим тоже, думаю, все понятно. 

9. 10

toString() принимает числовой параметр (необязательный) и toString(16) означает, что число записано в шестнастеричной системе счисления, посему ответ и 10. 

10. 28

016 это восьмеричное представление числа 14 в десятеричной системе счисления. 

11. -1 


12. [ "c" ]

Отдельно стоящий символ в той строке только один - "с", это и ищет указанное регулярное выражение. 

Текущий рейтинг: 5.0 (4 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Минимальная зарплата

clock апреля 27, 2009 01:34 by author Подлипенский Павел

Думаю все уже в курсе, что у нас кризис (теперь кажется финансовый), впрочем как и у всех. И каждый понимает что ничего хорошего ему это событие не принесет. А одним из "благ" кризиса является минимальная зарплата, т.е. та сумма денег, за которую и вы не против поработать и шефу увольнять вас пока нет повода. Звучит неплохо, правда? Неправда. У большинства людей хорошо развито чувство собственничества, поэтому пока это не мое, мне все равно кто этим владеет, но как только оно стало моим - хрен кто это у меня отберет! А тут такое дело - зарплату понижают! Не буду больше растекаться по древу вот вам поучительный комикс на эту тему:

Текущий рейтинг: 3.8 (4 голосов)

  • Currently 3,75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


4 интересных онлайн презентаций для веб-разработчика

clock февраля 25, 2009 17:47 by author Подлипенский Павел

1. Ajax 101 | Workshop
Автор: Bill Scott | This presentation on SlideShare
Введение в программирование с помощью Ajax. Включает XMLHttpRequest, XML, JSON, JavaScript, HTML, CSS, Dom Scripting, Event Handling с небольшими примерами на YUI.


2. Modular CSS
Автор: Russ Weakley | This presentation on Slide Share
Вполне доступно (даже я понял) объясняется механизм построения правильного модульного CSS, что позволяет прятать/показывать отдельные CSS правила для отдельных браузеров, без различного рода уловок и обходных путей.

3. jQuery in 15 minutes
Автор: Simon | This presentation on SlideShare
Небольшое введение в JQuery. Функции, коллекции, работа со значениями и цепочками.

4. JavaScript Library Overview 
Автор Jeresig | This presentation on SlideShare
Интересный обзор популярных JavaScript библиотек (jquery, prototype, Scriptaculous...) для веб-дизайнеров.

Текущий рейтинг: 4.5 (4 голосов)

  • Currently 4,5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Video: Layout Engine Internals

clock февраля 17, 2009 00:02 by author Подлипенский Павел

Интересное видео в тему к предыдущему посту. Если вы еще не в курсе, как работает браузер - жмите на серенький треугольничек рядом с дядькой.

Текущий рейтинг: 5.0 (3 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Скаженi кабани: Оптимизируем операции с DOM'ом

clock февраля 16, 2009 02:00 by author Подлипенский Павел

Давно известно, что операции с DOM'ом весьма и весьма трудоемки. Потери в производительности заметны обычно в трех случаях:

  • когда скрипт выполняет манипуляции с деревом объектов (создает, удаляет или изменяет часть дерева)
  • если скрипт "заставляет" браузер перерисовывать (redraw) или перестраивать разметку (reflow) страницы
  • и наконец, в случае когда скрипт "ищет" один из узлов дерева объектов (если дерево большое).

Последний пункт я уже рассматривал в одной из статей своего цикла Скаженi кабани, на примере JQuery. Поэтому сегодня мы поговорим о первых двух. Эм...на самом деле я схитрил, и первый пункт представляет собой ни что иное, как причину появления второго пункта. Тогда сразу перейдем ко второму пункту и попробуем разобраться в терминах перерисовывать и перестраивать разметку:

Перерисовка страницы браузером происходит в случае, когда что-то визуально изменилось, но разметка страницы осталась прежней. Например, изменился цвет элемента или элемент стал видимым/невидимым (с помощью visibility: [hidden, visible], так как это не повлияет на разметку). Эта операция существенно влияет на производительность веб приложения, так как заставляет браузер пройтись по дереву объектов и определить какие элементы видимы и как они должны быть отображены.

Перестройка разметки страницы более дорогостоящая операция. Она происходит в следующих случаях:

  • при первой загрузке страницы. В случае с Firefox, перестройка может происходить несколько раз, по мере докачивания контента страницы;
  • когда вы добавляете или удаляете элементы DOM'a. Надо сказать, тут есть одно исключение - если вы добавили/удалили объект с абсолютным позиционированием, то это может и не привести к перестройке разметки страницы, так как позиция и размеры других элементов не были изменены;
  • когда стиль элемента изменен и он влияет на размер и положение этого либо других объектов;
  • когда вы пытаетесь обратиться к свойствам, требующим вычислений со стороны браузера (например, offsetWidth, clientHeight). А также в случае попытки получить вычисляемые CSS значения (с помощью getComputedStyle() или currentStyle в IE).

Процесс перестройки разметки страницы выглядит примерно следующим образом:

Mozilla.org

Wikipedia

Но перестройка разметки странцы не происходит сразу после добавления элемента в дерево или после изменения высоты элемента. Все "запросы" на перестройку разметки выстраиваются в очередь и выполняются уже после выполнения скрипта. Причем, некоторые "запросы" могут быть объединены, если они применяются к одному элементу и являются одного типа (например изменяют его ширину). Но процесс оптимизации таких "запросов" сильно зависит от типа браузера (и даже версии браузера). Пользователь не может взаимодействовать с вашим приложением, пока идет перестройка разметки.

Теперь когда мы в курсе "почему наш сайт тормозит", рассмотрим несколько техник оптимизации работы с DOM'ом. Первое что приходит в голову, это минимизировать количество дорогостоящих операций (описанных выше). А значит, необходимо как можно больше операций совершать вне DOM'а, например используя DocumentFragment.

var products = ... //init array of products
var list = document.getElementById("myProducts"); //find list populate to
for (var i=0; i < products.length; i++){
    var item = document.createElement("li");

item.appendChild(document.createTextNode("Product" + products[i]);
    list.appendChild(item); // AHTUNG! Operation with DOM
}

Предыдущий код можно оптимизировать следующим образом:

var products = ... //init array of products
var list = document.getElementById("myProducts"); //find list populate to
var fragment = document.createDocumentFragment(); //create document fragment
for (var i=0; i < products.length; i++){
    var item = document.createElement("li");
    item.appendChild(document.createTextNode("Product" + products[i]);
    fragment.appendChild(item); //working with fragment only, not with DOM
}
list.appendChild(fragment); //add fragment to DOM

Эта версия кода затрагивает дерево объектов только раз, в последней строчке. И так как DocumentFragment не имеет визуальной составляющей, то все операции с ним не вызывают ни перерисовки, ни изменения в разметке страницы. Но так как DocumentFragment не может быть добавлен в DOM, то операция appendChild добавит все дочерние элементы фрагмента (вместо того, чтобы добавить сам фрагмент).

Другим, более эффективным подходом, будет работать с элементом, не находящимся в дереве. К примеру, мы можем удалить наш объект из дерева перед выполнением операций над ним (removeChild() или replaceChild())

var products = ... //init array of products
var list = document.getElementById("myProducts"); //find list populate to
var parent = list.parentNode; //find parent
parent.removeChild(list); //remove list element from DOM
var fragment = document.createDocumentFragment(); //create document fragment
for (var i=0; i < products.length; i++){
    var item = document.createElement("li");
    item.appendChild(document.createTextNode("Product " + products[i]);
    list.appendChild(item);
}
parent.appendChild(list);

Мы не избежали перестройки разметки страницы, но мы уменьшили количество таких перестроек.

Другой причиной перерисовки или перестройки страницы служат стили и спобосы их назначения элементам. Рассмотрим следующий кусок кода:

element.style.backgroundColor = "white"; //will cause redraw
element.style.color = "red"; //will cause redraw
element.style.fontSize = "12em"; //will cause reflow
element.style.widht = "100px"; //will cause reflow

Как видите первые две строки инициируют перерисовку. Избежать этого можно, если перед изменением стилей скрыть элемент с помощью visibility:hidden или display:none (будет произведено два лишних reflow). Избежать перестройки разметки тут не получиться, но их количество можно уменьшить, если задать все изменения стилей в CSS классе.

.newClass{
background-color: blue;
color: red;
font-size: 12em;
with: 100px;
}

а затем

element.className = "newClass";

Скрытый reflow может также произойти, если мы попытаемся получить одно из вычисляемых свойств (например offsetWidth). Браузер должен быть уверен, что значение свойства актуально, поэтому он рассчитает его заново, а это фактически и будет перестройка разметки страницы. Избежать этого опять же нельзя, но мы можем уменьшить количество таких операций за счет кэширования значения этого свойства:

var posElem = document.getElementById('animation');
var calcWidth = posElem.offsetWidth;
posElem.style.fontSize = ( calcWidth / 10 ) + 'px';
posElem.firstChild.style.marginLeft = ( calcWidth / 20 ) + 'px';
posElem.style.left = ( ( -1 * calcWidth ) / 2 ) + 'px';
... other changes ...

Полезные ссылки

Notes on HTML Reflow

Dom document fragments

Efficent Javascript (from Opera)

Increasing appendChild Performance with DOM Tricks

Текущий рейтинг: 5.0 (4 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Производительность браузеров в зависимости от верстки

clock февраля 13, 2009 09:17 by author Подлипенский Павел

Честно говоря раньше не придавал особого значения такой фазе веб-девелопмента, как верстка. Отчасти потому что никогда этим сам не занимался(на должном уровне), отчасти от того, что недопонимал некоторые аспекты веб-разработки. Недавно наткнулся на интересную статью Сергея Чикуенока (из команды никому не известного Артема Лебедева). Суть этой статьи сводится к следующему: если клиентский код работает медленно - убейте дизайнера, верстальщика или кто этим у вас там занимался. Потому как разметка влияет на скорость работы веб-приложения. Кому интересно почитать детали можно в оригинале статьи, а я лишь процитирую выводы:

    1. Для интерактивных элементов лучше использовать position: absolute.
    2. Большое количество элементов на странице может снизить производительность, но не стоит увлекаться их сокращением в ущерб надежности макета.
    3. Не надо делать очень глубоких вложенных структур элементов.
    4. Прежде чем начинать верстку макета, следует узнать, какие интерактивные механизмы там должны быть — это избавит от многих проблем уже на начальном этапе работы над проектом.
    5. Не надо загонять себя в угол глупых стереотипов: «валидность» и «семантичность» никому, кроме самих разработчиков, не нужна.
    6. Не стоит без надобности растягивать картинки. Если это необходимо сделать, следует воспользоваться canvas.
    7. Как правило, img-элемент будет работать гораздо быстрее, чем CSS-свойство background-image.
    8. Помните главное правило: оптимизировать нужно то, что требует оптимизации.

Вот так-то господа, веб разработчики...

Текущий рейтинг: 3.9 (7 голосов)

  • Currently 3,857143/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Небольшой LINQ пазл

clock февраля 11, 2009 10:25 by author Подлипенский Павел

 

Почему следующий кусок кода генерирует StackOverflowException?

IEnumerable<int> q = new int[] { 1, 2 };
q = from x in new int[] { 1, 2 }
    from y in q
    select x + y;
q.ToArray();

С предложениями, как это исправить - прошу в комментарии ;)

Текущий рейтинг: 5.0 (5 голосов)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Search


LinkedIn Profile

Tags

Posts

  • Эх, парсер скобку включил в ссылку Википедии. Правильная ссылка: http://en.wikipedia.org/wiki/NaN
    wyxa

  • to Left: >>NaN - это такое же число как 0 или 3.14 или 10e6 (хотя в нём и нет ни одной цифры) С одной стороны, NaN == "Not a Number" (http://en.wikipedia.org/wiki/NaN) с другой стороны, typeof NaN == "number" И где здесь, логика? ;)
    wyxa

  • Почему обьектом? Это всё равно что сделать число 0 обьектом, а все остальные начиная с 1 - числами :) NaN - это такое же число как 0 или 3.14 или 10e6 (хотя в нём и нет ни одной цифры).
    Left

  • to Left: то понятно, что так сделали :) но вопрос в причине, почему ее сделали именно числом, а не, скажем, объектом как null?
    Подлипенский Павел

  • 3. "number" Логического объяснения этому я не нашел, единственное что могу посоветовать, это стараться использовать isNaN вместо typeof SomePotentialNumber, во избежание казусов. А что здесь нелогичного? NaN - это тоже числовая константа, она тоже представима в виде числа с плавающей точкой для сопроцессора. Просто по соображениям упрощения совместимости с тем же самым сопроцессором NaN никогда никому не равен, даже самому себе. Потому и понадобилась функция isNaN.
    Left

  • Пункт 2 никакого отношения к яваскрипту не имеет. Это стандартный результат для любого языка использующего восьмибайтовую упаковку чисел с плавающей точкой согласно общепринятому стандарту IEEE 754. Непонимание особенностей представления чисел в различных системах счисления и особенностей последующей работы с ними - это маркерный вопрос. Если такой "разработчик" учился в техническом вузе - значит прогуливал лекции. Если не учился - значит просто ещё слишком молодой.
    enternet

Categories

Calendar

<<  Июль 2009  >>
воповтсрчепясу
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Archive

© Copyright 2009

Sign in

Ó÷àñòíèê ïëàíåòû Developers.org.ua

Bookmark and Share

Web Developement Blogs - Blog Catalog Blog Directory