Применение метода hasOwnProperty() в конструкции for…in
Поскольку в JS массивы не ассоциативны, разработчики используют объекты как хеш-таблицы. Перебирать все свойства объекта можно с помощью циклической конструкции for…in:
for (var prop in someObject) { alert(someObject[prop]); // выводим значения свойств }
Важно знать, что цикл перебирает все свойства объекта в цепочке прототипов. Эта особенность является проблемой в том случае, если Вы хотите использовать только те свойства, которые существуют в самом объекте. Проблема решается с помощью метода hasOwnProperty():
Свойства-объекты или «иногда прототип это зло
Объявление всех свойств в прототипе может привести к незапланированному разделению одного и того же свойства разными объектами.
Например, объявим объект класса хомяк(Hamster). Метод found набирает еду за щеки, набранное хранит в массиве food.
function Hamster() { } Hamster.prototype = { food: [], found: function(something) { this.food.push(something) } }
Создадим двух хомячков: speedy и lazy и накормим первого:
speedy = new Hamster() lazy = new Hamster() speedy.found("apple") speedy.found("orange") alert(speedy.food.length) // 2 alert(lazy.food.length) // 2 (!??)
Как видно — второй хомяк тоже оказался накормленным! В чем дело?
Причина заключается в том, что food не является элементарным значением.
Если при простом присвоении hamster.property=»…" меняется свойство property непосредственно в объекте hamster, то при вызове hamster.food.push(…) — яваскрипт сначала находит свойство food — а так, как в hamster его нет, то оно берется из прототипа Hamster.prototype, а затем вызывает для него метод push.
На каком бы хомяке не вызывался hamster.food.push(..) — свойство food будет браться одно и то же, из общего прототипа всех хомяков.
Мы получили пример «статического свойства класса». Да, оно бывает полезно. Например, мы можем разделять общую информацию между всеми хомяками посетителя.
Но в данном случае такое ни к чему.
Чтобы разделить данные, неэлементарные свойства обычно присваивают в конструкторе:
function Hamster() { this.food = [] } Hamster.prototype = { food: [], // просто для информации found: function(something) { this.food.push(something) } }
Теперь у каждого объекта-хомяка будет свой собственный массив food.
Свойство food в прототипе оставлено как комментарий. Оно не используется, но может быть полезно для удобства документирования.
for (var prop in someObject) { if (someObject.hasOwnProperty(prop)) { alert(someObject[prop]); // выводим значения свойств } }
Этот код выводит значения только тех свойств, которые непосредственно существуют в someObject.
Излишняя манипуляция c DOM
Излишнее взаимодействие с DOM, значительно снижает производительность вашего кода:
// anti-pattern for (var i = 0; i < 100; i++){ var li = $("<li>").html("Элемент номер #" + (i+1) ); $("#UL").append(li); }
Этот код изменяет DOM 100 раз, и в добавок создает 100 объектов jQuery. Намного рациональнее задать цикл, который сгенерирует 100 элементов, запишет их в строку и занесет ее в HTML. В этом случае взаимодействие с DOM происходит один раз:
var listString = ""; for (var i = 0; i < 100; i++){ listString += "<li>Элемент номер #" + (i+1) + "</li>"; } document.getElementById("UL").innerHTML(listString);
Если необходимо создать вложенные списки то метод конкатенации строк не подходит. Потребуется записать элементы в массив:
var subString = "<li><ul>" var subArray = []; for (var i = 100; i > 0; i--){ sublisttMas.push("Элемент номер #" + (i+1)); } subString += subArray.join("</li><li>") + "</ul></li>"; document.getElementById("UL").innerHTML(subString);
Это — один из самых быстрых и легких способов сгенерировать вложенные списки без использования дополнительных библиотек.
Сравнение значений типа Boolean
Сравнение булевых значений в условии является пустой тратой производительности:
if (netcribe == true) { // do something for true } else { // do something for false }
Обратите внимание на условие: netcribe == true. Сравнение данной переменной со булевым значением не имеет смысла, поскольку netcribe уже логическое значение.
if (netcribe) { // do something for true } else { // do something for false }
если нужно сравнить со значением false, используем логические НЕ
if (!netcribe) { // do something for true } else { // do something for false }
Присвоение событий
Event — представляет собой сложный JavaScript объект. Для простоты понимания используется jQuery (принципы всплытия и погружения объекта события одинаковы с нативным JS кодом). Представим следующую задачу: необходимо чтобы при клике на ссылку, открывалось модальное lightbox окно:
Соответствующий HTML код:
<div id="container"> <a href="someimage.jpg"><img src="someimage-thumb.jpg"></a> <a href="someimage.jpg"><img src="someimage-thumb.jpg"></a> <a href="someimage.jpg"><img src="someimage-thumb.jpg"></a> </div>
Не корректный JS код:
$('a').on('click', function() { callLightbox(this); });
В данном примере из за погружения Event объекта, событие может принадлежать не элементу <a>
, а самому изображению <img>
, из за чего функция callLightbox() сработает не верно.
Корректный JS код:
$("#container").on("click", "a", function(event) { callLightbox(event.target); });
В этом случае используется event.target и событие будет присвоено к элементам <a>
Логически несовместимые имена переменных и функций
Несовместимые имена переменных и функций могут стать большой проблемой для Вас и для других людей работающих с вашим кодом. Важно создавать логически верные имена переменных:
var url = "http://netcribe.com"; var browser = "Firefox"; var lang = "PHP";
Для примера, не корректно было бы добавить еще одну переменную somethink, это бы внесло противоречия в модель именования переменных. Вот почему константы в большинстве языков традиционно определяются с заглавными буквами.
Корректная грамматическая структура наименования функций:
function subtractFive(number){ return number - 5; } function addFive(number){ return number + 5; }
В определенных случаях имя функции определяется ее значением. Например, функцию которая возвращает HTML строку можно называть getTweetHTML().
Имена функций конструкторов и классов как правило начинаются с заглавной буквы:
function Dog(color){ this.color = color; }
Создавайте понятные имена ваших переменных и функций, классифицируйте их вместе с другими похожими идентификаторами — это позволит Вам и другим людям намного проще ориентироваться в коде.
Спасибо всем за внимание.
ссылка на оригинал статьи http://habrahabr.ru/post/161809/
Добавить комментарий