Kaspiy, форматирование - это не столько отступы между строчками, сколько отступы слева. Ну у меня же масса кода написана. Ты же видишь, что он написан "лесенкой": какие-то строчки сдвинуты вправо пробелами сильнее, чем другие? Если ты не понимаешь этого, ты спросил "почему так?" Не спросил. А это и есть форматирование. Как оно делается? Любая управляющая конструкция (function, if, for, while, switch, with и т.д.) может содержать в себе код - этот код "глубже" задвигается, чтобы видеть, где начало, а где конец конструкции.
Дальше, если ты добавляешь div, и не работает, это не значит, что div неправильный, и его надо менять на что попало. Причина ошибки может быть в другом, и как раз её надо найти. Ты не ответил на вопрос: смотрел ли ты ролики, как работать с отладчиком, и пробовал ли отлаживать сам? Ты хотя бы список ошибок и замечаний от браузера на свой код видел? Игра в "угадайку" - это очень нудное, трудоёмкое и бессмысленное занятие. К сожалению, мы тут ею и занимаемся.
Молодец, что прокомментировал строчки. Давай посмотрим:
function stopTime() { // остановка таймера
var y; //назначил переменную для stopTime
}
Почему
Sla требует форматирования? Где начало, где конец функции, что внутри, что снаружи функции? Вот непонятно, ты это видишь или не видишь? Было бы форматирование, было бы понятно, что и как ты видишь.
Я скопировал твою функцию от начала и до конца. Поясни её смысл. Что она должна делать по замыслу? Что она делает на самом деле?
Не очень понятно, почему после моего примера у тебя стали массово появляться тут и там переменные x, y и т.д. Мой пример был - пример конструкций: их синтаксис - форма записи, и семантика - какой смысл имеет область видимости. Этот мой пример вообще ничего не делает полезного. Ты же его воспринял как нечто, что можно взять и скопировать себе. А зачем? Программирование - это ж не шаманство: взять кусочек, вставить себе, и ура - получилось. Это написание осмысленного кода. Если ты берёшь чужой код, значит ты его прочитал так, будто написал сам, убедился, что он в точности делает то, что нужно, и только потом вставил себе.
Согласен со
Sla - не будем двигаться вперёд, пока не разберёмся с имеющимся. А то информации много, и на пользу это пока не идёт.
Итак, во-первых, отформатируй код, во-вторых, в коде в комментариях поясни не фразой "остановка таймера", а опиши всю синтаксическую конструкцию: как она называется, какой у неё идентификатор (если есть), как вычисляется выражение (если есть выражение) - каждую скобку, каждую запятую, потому что в языке у них есть конкретный смысл, и этот смысл ты должен знать так хорошо, что ночью тебя разбуди - ты сразу сможешь объяснить.
Например:
function stopTime() { // Объявлена функция stopTime, эта функция предназначена для остановки таймера, функция начинается
var y; // Объявлена переменная y, локальная для функции stopTime, смысла никакого не несёт
} // Закончилась функция stopTime
И сразу видно, какая написана бессмыслица: действия никакого нет, зачем туда "впендюрена" y - непонятно, мысль автора остаётся туманной и загадочной для читателя.
Т.е. главная задача, направить эти мысли автора в конструктивное и правильное русло.
Как читаются синтаксические конструкции. Разберём по шагам "под микроскопом", что называется. Отсюда же будет видно, что форматировать.
Вычленяем из текста ключевые значки:
function ()
Значит это место - объявление функции.
Затем ищем идентификатор - как функция называется в коде:
function checkTime()
понимаем, что функция называется checkTime. Т.е. объявлена функция checkTime.
Дальше смотрим, есть ли у неё параметры:
function checkTime(i)
Видим параметр i. Т.е. объявлена функция checkTime с параметром i. Всё это вместе называется "заголовок функции".
У любой функции помимо заголовка есть тело. Тело записывается внутри фигурных скобок:
function checkTime(i) {
}
Вот видим объявление функции checkTime, с параметром i, состоящей из заголовка и тела функции.
Всё, что внутри тела функции - записывается с отступом. Там должны следовать операторы один за другим последовательно.
Какой первый оператор внутри функции? Видим ключевое слово if, за ним скрывается условная конструкция. Любая условная конструкция может быть сокращённого вида
if() ;
а может быть полного вида:
if() ; else ;
Полный вид отличается от сокращённого наличием слова else. Есть у нас после if слово else внутри checkTime - нету, значит конструкция сокращённая. Итак функция с первым её оператором:
function checkTime(i) {
if() ;
}
Условие строится таким образом, что внутри круглых скобок должно стоять вычисляемое выражение, которое даёт ответ "истина" или "ложь". Что это за выражение?
function checkTime(i) {
if( < ) ;
}
Это двуместный оператор сравнения "<" - "меньше", означающий, что результат подвыражения слева должен быть меньше результата подвыражения справа. Оба результата подвыражений должны быть одного типа, и должны быть либо числами, либо строками.
В нашем случае в левом подвыражении находится переменная i, т.е. смотрится, что внутри неё записано,
function checkTime(i) {
if(i < ) ;
}
а в правом подвыражении константа 10 - число.
function checkTime(i) {
if(i < 10) ;
}
Раз 10 - число, значит и внутри i предполагается число. В итоге смысл выражения такой: "числовое значение переменной i меньше числа 10?". На это можно ответить "да" или "нет" - как раз подходит для if.
В итоге объявлена функция checkTime, с параметром i, внутри функции первым делом проверяется условие, является ли числовое значение параметра i меньше числа 10.
После круглых скобок оператора if должен следовать оператор, содержащий код, выполняющийся только при "срабатывании" условия. Что это в нашем случае за оператор такой? А это оператор блока кода - фигурные скобки "{" и "}". Точно такой же, как у тела функции. Он позволяет внутри себя включать несколько последовательных операторов.
function checkTime(i) {
if(i < 10) {
}
}
Что внутри блока кода, исполняемого по условию? А там оператор присваивания. И раз он внутри, мы его опять записываем с отступом:
function checkTime(i) {
if(i < 10) {
= ;
}
}
Это тоже двуместный оператор, слева от него должна быть обязательно переменная, а справа любое вычисляемое выражение. Какая у нас переменная слева? А это всё тот же параметр i.
function checkTime(i) {
if(i < 10) {
i = ;
}
}
Справа мы видим сложное выражение. Такие выражения мы можем помещать в оператор круглые скобки "(" и ")", чтобы чётко видеть границы составных частей выражения и понимать порядок их выполнения:
function checkTime(i) {
if(i < 10) {
i = ();
}
}
Внутри сложного выражения мы находим оператор "+" - тоже двуместный, означающий либо сложение чисел, либо сцепление (конкатенацию) строк.
function checkTime(i) {
if(i < 10) {
i = ( + );
}
}
Слева и справа от оператора "+" могут быть подвыражения, и они должны иметь общий тип: либо оба быть строками, либо оба быть числами. Слева у нас строковая константа "0":
function checkTime(i) {
if(i < 10) {
i = ("0" + );
}
}
Значит справа тоже должно быть строковое выражение. А что мы там видим? А мы там видим всё тот же пераметр i функции, значение которого и берётся.
function checkTime(i) {
if(i < 10) {
i = ("0" + i);
}
}
Ну и поскольку это достаточно простое выражение, то круглые скобки тут необязательны при записи:
function checkTime(i) {
if(i < 10) {
i = "0" + i;
}
}
Больше в функции ничего нет.
Kaspiy, твоя задача научиться видеть код вот так вот подробно, в уме уметь проговорить "прочитать" любую конструкцию, задумываться над каждой буковкой.
Теперь критически посмотрим на эту функцию и на логику её работы:
1) Внутри условия мы выяснили, что i должно быть обязательно числом, а внутри оператора "+" та же самая i должна быть непременно строкой. Как же это работает? А так, что преобразование типа делается неявно. И это - не очень-то хорошее дело, это то, что программист фактически упустил из виду. Тогда уж лучше явно указывать типы выражений и преобразования:
function checkTime(i) {
if(Number(i) < 10) {
i = "0" + String(i);
}
}
Никаких "подразумевается".
2) Ещё интересно, что функция не возвращает никакого результата, однако в том месте, где функция используется, явным образом от неё ожидается результат, например:
m=checkTime(m); //проверяем минуты
Что будет записано в переменную m в операторе присваивания? Результат функции checkTime. А где внутри функции checkTime возвращается результат? Нигде. Как же это работает? А так, что последнее упомянутое выражение "неявно" считается результатом. Опять программист не контролирует, что происходит. Никаких "неявно", никаких "подразумевается" - должны вернуть результат:
function checkTime(i) {
if(Number(i) < 10) {
i = "0" + String(i);
}
return i;
}
Это делает оператор return. Он завершает работу функции (т.е. весь код внутри блока после return не работает), и возвращает результат функции - его можно использовать снаружи в выражениях и для присваивания.
3) Внутри функции параметр i не только читается, но и переписывается. Это выходит так, что в месте вызова функции должна находиться переменная, передаваемая по ссылке, и запрещены любые вычисляемые выражения, иначе результат всей работы просто пропадёт. Или, наоборот, если вместо выражения подставить переменную, эта переменная на вызывающей стороне изменится. Это подход вредный и опасный, потому что использующий функцию программист никак такого "подвоха" не ожидает. С этим явлением надо бороться. Борются с ним с помощью внутренней локальной переменной, куда один раз копируется значение параметра. Дальше параметр сам по себе, а с внутренней переменной можно делать что угодно - она никому снаружи не видна и не интересна.
function checkTime(i) {
var r = i;
if(Number(r) < 10) {
r = "0" + String(r);
}
return r;
}
4) Задумчивость вызывает сравнение i < 10. Т.е. если i = 3, то результат будет "03" - хорошо. Но если i = -33, то результат будет "0-33" - а оно нам надо? Это получается, что опять неявно, опять предполагается, что функция получит в качестве i только положительные числа, да ещё и, похоже, целые. Ни с дробными, ни с отрицательными, ни с нечислами никакой внятной работы функции не будет. Гораздо правильнее будет работать со строчкой, в которой гарантированно находится число, гарантированно целое и положительное, и гарантировано в 1 цифру. Как этого достичь? Например, так:
function checkTime(i) {
var r = String(Number(i));
if(r.length == 1) {
r = "0" + r;
}
return r;
}
Сначала мы преобразуем значение параметра i в число, чтобы это было гарантированно число. Если параметр содержит что-то, что в число не преобразуется, будет число NaN. Затем мы сразу же это число преобразуем в строчку. Что получается? Если это число не целое, там заведомо будет десятичная точка или запятая, - т.е. длина строчки заведомо больше 1, если это отрицательное число, там будет минус, и опять длина заведомо больше 1, если там будет NaN, длина этой строчки заведомо больше 1. Т.е. получат строчку длиной 1 только неотрицательные целые числа от 0 до 9. Поэтому можно написать условие по длине строки: если длина строки 1, то добавляем слева "0", иначе возвращаем как есть без изменений. И если снаружи в функцию передали что-то неподходящее, то никаких дополнительных нулей прибавляться не будет.
Kaspiy, Итак, в десятый раз повторяем: разбери, отформатируй, объясни, вникни в код, который ты написал. Если ты не знаешь чего-то, какое-то выражение непонятное, у тебя нет объяснения - не "шамань" по принципу "авось заработает", задай конкретный вопрос: "что вот от сих до сих я выражения не понимаю - объясните".