Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: для новичков > Важные моменты в программировании на JavaScript


Автор: Aliance 6.6.2005, 22:12
Думаю, необходимо создать такую тему, где бы описывалось, что нужно знать и помнить человеку, программирующему на JavaScript.

Итак, прежде всего это контейнер, в котором все чудо и происходит.
Лучше всего писать полностью, так:
Код

<script type="text/javascript" language="JavaScript">
<!--

/* тут непосредственно сценарий */

// -->
</script>


Аттрибут type указывает на то, что это сценарий JavaScript (как MIME-тип)
Необязательный аттрибут language сообщает веб-браузеру, на каком языке написан сценарий. Это нужно для тех случаев, когда браузеры, не понимающие указанный язык, пропускают этот контейнер.
Значения:
  • JavaScript
  • VBScript
Спецификация HTML4 отвергает этот аттрибут, и отдает предпочтение аттрибуту type

Далее, часто возникает ситуация, когда необходимо динамически добавить тег <script>. Обычно дилетанты делают это так:
Код

document.write('<script>');
document.write('/* js */');
document.write('</script>');

Но это не есть корректно, т.к. интерпритатор JS, встречая закрывающий тег <script> - прекращает работу сценария, остальное выводится как код HTML. Соответственно правельно будет так:
Код

document.write('<script>');
document.write('/* js */');
document.write('<\/script>');
// или
document.write('<script>');
document.write('/* js */');
document.write('</sc'+'ript>');


Далее, стоит комментаровать свои сценарии и делать удобочиваемыми:
Код

function qwerty() { alert('jjjjj'); var a = b; var c = d; }

можно и нужно записать так:
Код

function qwerty() {
   alert('test');
   var a;
   id (a) {
      alert('aaa');
      if (true) {
         alert('true');
      }
  }
}


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

Еще одна интересная история случается, когда в качестве, скажем, индефикатора функции использовать глобальный метод или в качестве имени переменно - зарезервированное слово = то возникает ошибка времени исполнения. У меня такое случалось с таким кодом:
Код

function do() {
   alert('test');
}

Т.к. do - глобальный метод. Писалось о необходимости в наличии while (do/while - цикл)

Итак, постим сюда свои наблюдения и находки, изощрености и прочее. smile

Автор: Opik 6.6.2005, 23:42
Не помню, когда именно возникает. Вроде при несовпадении типов, например:
Код

<script>
   function plus()
   {
       el = document.getElementById("c");
       all = c.value + 1;  
       alert(all);
   }
</script>
<input type="text" id="c" value="10" /> <input type="button" value="+1" onclick="plus()" />

решение:
Код

<script>
   function plus()
   {
       el = document.getElementById("c");
      // parseInt - приводим к типу Число. и работаем с ним.
       all = parseInt(c.value) + 1;  
       alert(all);
   }
</script>
<input type="text" id="c" value="10" /> <input type="button" value="+1" onclick="plus()" />

Автор: Aliance 6.6.2005, 23:52
Цитата(Opr @ 7.6.2005, 00:42)
      el = document.getElementById("c");
      all = c.value + 1;

может так:
Код

var el = document.getElementById("c");
var all = el.value + 1; 

Но естественно, что результат будет не таким как ожидалось. Описал тут:
http://forum.vingrad.ru/index.php?showtopic=54409&view=findpost&p=432827

Автор: Opik 6.6.2005, 23:54
Aliance
да, я знаю. а чем плохо, что переменные становятся глобальными?
а разница toNumber или parseInt, второе как то мне больше нравится.

Автор: Aliance 6.6.2005, 23:55
Цитата(Opr @ 7.6.2005, 00:54)
а разница toNumber или parseInt

она есть, я приводил примеры. Сам с таким столкнуля =)

Цитата(Opr @ 7.6.2005, 00:54)
а чем плохо, что переменные становятся глобальными

Это не плохо. Скорее обычные меры предосторожности. Ведь глобальную переменную создавать нужно только специально. Иначе можно забыть про это и навредить себе 8))

Автор: Opik 6.6.2005, 23:59
Aliance
ок, учту. (про глобальные переменные.).
Однако parseInt - аналог intval в PHP. Она поступает полностью аналогично. Я выбрал её не случайно.

Автор: Sardar 7.6.2005, 01:34
Цитата(Opik @ 6.6.2005, 22:54)
а чем плохо, что переменные становятся глобальными?

Если функция вызовет сама себя рекурсивно или где в других функцих используються те же имена(часто итератор i) то появляються трудно находимые глюки smile

Помимо обьявления локальных переменных в функциях (var peremennaja), не стоит забывать что JS это обьектно - (*) язык (звёздочку понимайте как хотите лишь бы вам думать не мешало smile ). Если пишем что то, то создавайте сущности описывающие процесс или обьект. Например меню(контейнер), в меню опции и т.д. а не просто массивы. Ваш код станет более прост и читабельней, ведь:
Код
menuSet.show("submenu3"); //читаеться проще чем 
show_menu(menuset["submenu3"], true);

Естественно код становиться короче и проще, ведь код в каждом обьекте будет описывать всё необходимое для работы только с этим "типом" обьекта.

Полезно не пользоваться старыми способами адресаций типа: document.all или просто document.что_либо. Во первых это ведёт к не переносимому на новые платформы коду. Во вторых коллекции содержат элементы не только по идентификатору, но и по имени, в результате получаем коллизии имён/ИД. Нет стандартного действия в такой ситуации, браузер может выдать список всех элементов с таким именем/ИД или просто первый встречный элемент.
Вывод: задаём уникальные идентификаторы(а это не всегда нужно smile ) необходимым элементам, выбираем сие по document.getElementById

На счёт идентификаторов третий совет: елси вы генерите скриптом кучу кода(допустим меню), то не задавайте вашим субэлементам идентификаторы типа ("префикс_"+счёчик). Гораздо проще положить все элементы в дополнительный контейнер(например div) и работать с элементами через W3C DOM. Другими словами задайте правильную логичную структуру тому что вы генерите и это сыграет вам на руку.

Автор: Dave 28.7.2005, 12:15
Цитата(Sardar @ 7.6.2005, 01:34)
Цитата(Opik @ 6.6.2005, )
а чем плохо, что переменные становятся глобальными?

Если функция вызовет сама себя рекурсивно или где в других функцих используються те же имена(часто итератор i) то появляються трудно находимые глюки smile

то есть в ф-ии когда пишем var variable_name
то переменная локальная а если без var то глобальная, я правильно понял ?
а как поступить с итератором i в ф-ии чтобы он был локальным? написать предварительно var i =0; ?


...кажется нашел, в ф-ии в цикле можно так написать
Код

 for(var i=0; i<arguments.length; i++) ...

Автор: Гость_12345 7.12.2005, 15:14
Приёмы в написании кодов JS.
Для сокращения длинных записей и улучшения читаемости:
Код

1. d=document;

2. Ev='if(!e)e=event;';
   d.onclick=function(e){eval(Ev); ... ( обращаться к event через e) } 
    //--для кроссбраузерного доступа к событию в обработчике события
   <... onClick=func(event) ...>

3. function func(e){ ... ( обращаться к event через e) } 
    //--для вызываемой функции по событию

4. <... onClick=return!1 ...> -- вместо <... onClick="return false" ...>
   //вообще, <... onClick=любой_текст_JS_без пробелов_не требует_кавычек ...>
   //например, <... onClick=a=b=12345;alert('click\x20on\x20tag')>

5. d.ID=function(I){return this.getElementById(I);}
    //--чтобы вызывать не document.getElementById('...'), а
   d.ID('...')

6. А=[1,2,3];        //а не A=new Array(1,2,3);
   A=[];        //а не A=new Array();
   Im=[new Image(),new Image()];    //а не Im=new Array();for(i=0;i<2;i++)Im[i]=new Image();

Автор: Гость_12345 7.12.2005, 15:15
Код
7. if((Src=FF?e.target:e.srcElement).id.charAt(0)!="x") ... ;
    //--объявлять переменные по ходу использования, а не заранее,как в 
    Src=FF?e.target:e.srcElement;
    if(n.id.charAt(0)!="x") ... ;

8. if(self.win1 && win1.document && win1.document.formInWin1) ...;
    //--пользоваться невычислением выражений после && , если первый аргумент false

9. alert([12,23,aaa,xxx]);    //чтобы не писать +" "+ вместо запятой.

10. v='visible';hid='hidden';
    (...).style.visibility=v;    (...).style.visibility=hid;

11. setTimeout(func,500);    //запуск функции с задержкой без аргументов

12. (function func(){alert(999);})()    //запуск функции в контексте объявления

Автор: Sardar 7.12.2005, 17:00
Цитата
Для сокращения длинных записей и улучшения читаемости:

Не согласен, d менее читаемо чем document, наработано опытом smile

2) а зачем eval то?

4) одна из самых плохих привычек - опускание кавычек. Такой код не читаем стандартными парсерами, это кстати одна из причин создания XHTML. Совет вем: не опускайте кавычки и не сокращайте логичное и ясное false до !1

5) DOM придумывался как стандартный интерфейс к деревьям документов. Имена методов долзны запоминаться как они есть, т.к. помимо JS есть и другие языки, где W3C DOM актино используеться и имена те же самые. document.getElementById сразу ставит все точки над i, d.ID вводи в заблуждение выигрывая несколько символов в коде... не на том экономишь smile

7) люблю так писать, но большинство народу не любят такую запись, т.к. менее читаема. Согласен с ними, но по прежнему пишу кратко smile

9) можно и так alert([12,23,aaa,xxx].join(' ')); с пробелом, кстати технически этот код не обязательно тeрбует больше ресурсов чем просто со строками, в своём Trilobite Scripting Language (скриптовое окружение для eZ80) выбрал стратегию экономить на памяти, с массивом код по идее должен отрабатывать быстрей. Не знаю как реализованно в JS браузера.

10) и зачем эти пару символов экономить, нужно думать над алгоритмом, писать эффективно. Сэкономленные пара байт не заметны для пользователя, даже если он на самом убогом модеме, за то ты сам будешь долго материться если придёться переделывать такой код года через полтора smile

Автор: Ciber SLasH 7.12.2005, 17:34
Полностью согласен с Sardar.

2Гость_12345:
Твой код иногда сложновато разобрать, приходится повторно смотреть, что же это за d.<что-то>. Конечно я согласен с: "Если писать только для себя скрипты и разработать определённые правила (типа: d - это document; d.ID - это document.getElementById), то конечно можно писать как можно меньший код, опуская точки с запятой, придумывать ещё какие-то сокращения, бороться за байты в документе... Но если твой код прийдётся смотреть другим людям, то у них явно возникнут проблемы с пониманием твоего кода."

Автор: Гость_12345 13.12.2005, 17:43
Sardar: я перечислил выработанные для себя правила, например, знаю, что в своём коде не буду занимать имена d, v, hid, d.ID и некоторые другие под другие переменные. Некоторая надстройка над языком, принятая 1 раз и помогающая не отвлекаться на длинные имена и длинные выражения с длинными именами. У других - другие условности. Когда читаешь чужой код и есть желание разобраться, приходится учитывать.

2) а зачем eval то?
Чтобы 1 раз написать вверху кодов, а потом знать, что в каждом обработчике приводится объект event к имени "е". Обработчиков много, и тогда несущественные формальности мешают читать суть.

alert([12,23,aaa,xxx].join(' ')); не хочу ради краткости, при отладке.

5) DOM придумывался... document.getElementById), ...
Другие языки будут с этими проблемами разбираться сами, а здесь она решается так.

> нужно думать над алгоритмом, писать эффективно
согласен, а эти приёмы мне помогают читать алгоритм в коде.

4) одна из самых плохих привычек - опускание кавычек. Такой код не читаем стандартными парсерами...
пока не использую парсеры и не планирую использовать их, не собираюсь утруждать себя следованию стандартам, написанным не для живого HTML. Так же, как var имя_переменной=...; в функциях. Когда задача перерастёт установленные рамки, это будет заметно по задаче, тогда и переучимся. Пока этого нет, не надо засотрять текст несущественным. Сравните: мы произносим слова так, чтобы это было понятно собеседнику, а не так, как написали бы то же самое в книге, чтобы удовлетворить всем. На этом пути начал Перл, но он же и рухнул под массой условностей - $i="$j$k";print$i; Ничего - взяли лучшее и пошли дальше.

Ciber SLasH У меня тоже возникают проблемы, когда экран засорён длинными выражениями с малым содержанием, какого размера экран бы ни был.

Автор: Sardar 14.12.2005, 00:50
Гость_12345 - явно минималист smile
Интересно что сам таким был, пока не столкнулся с коллективной разработкой. Не под каким либо давлением, а "по собственному разумению" врдруг приходишь к тому что писать нужно ясно и не забывать о коментариях, которые порой больше чем сам код smile

В любом случае я не советую другим пользоваться твоми приёмами, больше проблем.

Цитата
Чтобы 1 раз написать вверху кодов, а потом знать, что в каждом обработчике приводится объект event к имени "е". Обработчиков много, и тогда несущественные формальности мешают читать суть.

Код что в eval можно сразу вписать в функцию, всё равно меняться не будет, лишняя потеря в производительности.

Автор: Гость_12345 14.12.2005, 13:41
> Код что в eval можно сразу вписать в функцию
Когда речь о производительности, а не о наглядности, то другое дело. И d.ID придётся развернуть.

О комментариях не забываю, до коллективной работы не доходил. : )

Автор: Innuendo 6.1.2006, 01:43
а вот я часто себя ловил на document.write('text')
когда в text были аппострофы.. не понимал где ошибка smile... в таких случаях надо заводить вместо аппострофа его код: user posted image

Автор: Ciber SLasH 26.2.2006, 06:59
2Innuendo:
Ну это не апостроф, а одинарная кавычка, а апостроф имеет код & 096;
Кстати, если встречается одинарная кавычка или другие спец. символы, которые портят целостность данных, то эти спец. символы можно экранировать подстановкой перед спец.сим. обратного слэша \.
Т.е. будет так: \'
А ещё можно обрамить строку, в которой встречается одинарная кавычка, в двойные кавычки: "Д'Артаньян" или 'Д\'Артаньян'.

Автор: iamyri 26.3.2006, 09:48
Надо сразу привыкать помещать скрипты в отдельные файлы и закрывать их от роботов.

Автор: Vigoroso 5.8.2006, 22:43
что за роботы  smile 

Автор: Sardar 5.8.2006, 23:07
Поисковые боты, что бы скрипты не индексировали, хотя в этом ничего плохого нет, да и сами боты фильтруют всё кроме основного текста.

Автор: skyboy 29.8.2006, 11:14
при создании таблицы методом DOM если создавать:
table -> tbody -> tr -> td
то всё нормально. А если при создании упустить tbody, то в IE(только в нём) таблица будет 1х1 пиксел размером, а содержимое никак не захочет отобрадаться.

Автор: Sardar 29.8.2006, 11:55
skyboy, таблицы вообще тяжёлая вещь в браузерах, потому имеют свой API от W3C (смотрим DOM HTML). Строки лучше вставлять через insertRow, ячейки в строках через insertCell.

Автор: skyboy 29.8.2006, 13:40
Sardar, единообразие - хорошая штука smile а какие ещё проблемы при создании/изменении таблиц известно?

Автор: Sardar 29.8.2006, 13:43
innerHTML не переносят, не лечиться, согласно стандарту. Также <table>...</table> вставляемый в innerHTML любого блочного элемента убивает таблицу, лечиться оборачиванием в любой блочный элемент, например  <div><table>....</table></div>. Вроде всё smile

Автор: cruelangel 12.9.2007, 22:35
мда... гость - большой любитель спагетти smile желаю ему поковыряться в своём коде через пару лет...

Автор: Се ля ви 29.5.2008, 11:43
Цитата(Aliance @  6.6.2005,  22:12 Найти цитируемый пост)
Лучше всего писать полностью, так:
Код
<script type="text/javascript" language="JavaScript">
<!--
/* тут непосредственно сценарий */
// -->
</script>

В http://www.w3.org/TR/xhtml1`ной нотации http://www.w3.org/TR/xhtml1/#h-4.8:
Код
<script type="text/javascript" language="javascript1.2"><![CDATA[

    alert("<This is compatible with XHTML>"); //]]>
</script>


http://javascript.about.com/library/blxhtml.htm, можно писать так:
Код
<script type="text/javascript">//<![CDATA[
    
    alert("<This is compatible with XHTML>"); // ]]>
</script>

А вообще я это использую только при разработке, в готовых приложениях взял за правило всё выносить в отдельные файлы скриптов.

Автор: evilice 21.1.2010, 11:51
сокращать код, конечно, надо! Но делайте это с умом и комментируйте!
Так же исользуйте js-библиотеки (prototypeJS, jQuery...) - это упрастит процесс разработки не только Вам, но и другим разработчикам, которым, возможно, придётся разбираться в Вашем коде. + ко всему эти библиотеки прекрасно работают с DOM и AJAX и Вам не придётся изобретать велосипед!
На примере prototypeJS:
document.getElementById("element") можно заменить на $("element")
а document.getElementById("element").value на $("element").value или ещё проще V("element")

По поводу if(temp =! 1)
Старайтесь не сравнивать разные типы данных! (1 - Integer, false - boolean). Можно, ошибочно, подумать, что temp может принимать значения 2, 3, -100...

Автор: popov654 15.8.2011, 17:41
Цитата(Гость_12345 @  13.12.2005,  17:43 Найти цитируемый пост)
пока не использую парсеры и не планирую использовать их, не собираюсь утруждать себя следованию стандартам


Мда, тяжёлый случай  smile 

Автор: webguru 27.2.2018, 20:18
Вот нашел классный материал о  объектах и свойстве prototype.  http://webdiz.com.ua/glava5-obiekty-v-javascript/rasshirenie-obektov-svoystvo-prototype/

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)