Объясняем современный javascript динозавру
Содержание:
- Примечание по байт-коду
- Комментарии
- Класс GregorianCalendar
- 9) onReady()
- Цикл while()
- Куда развиваться JavaScript-программисту
- Оператор typeof
- Внешние переменные
- Языки «над» JavaScript
- Цикл for…of (новинка в ES6)
- Константы
- TypedAPI: клиент-сервер для TypeScript
- Examples in Each Chapter
- Use the Menu
- Learn by Examples
- Why Study JavaScript?
- Learning Speed
- Commonly Asked Questions
- JavaScript References
Примечание по байт-коду
Как и в случае с машинным кодом, не все компьютеры понимают байт-код. Чтобы интерпретировать его на машиночитаемый язык, необходимо промежуточное ПО, такое как виртуальная машина, или движок (например, Javascript V8). По этой причине браузеры могут выполнять этот байт-код из интерпретатора во время вышеупомянутых 5-ти стадий с помощью движков JavaScript.
В результате возникает следующий вопрос:
Является ли JavaScript интерпретируемым языком?
Да, но не совсем. На ранних этапах JavaScript Брендан Айк создал движок JavaScript ‘SpiderMonkey’. У движка был интерпретатор, который говорил браузеру, что нужно делать. Сейчас есть не только интерпретаторы, но и компиляторы, а код не только интерпретируется, но и компилируется для оптимизации. Технически все зависит от реализации.
- Прототипирование для Vue(Opens in a new browser tab)
- Как не лажать с JavaScript. Часть 1
- JavaScript async/await: что хорошего, в чём опасность и как применять?
Перевод статьи Mano lingam: JavaScript: Under the Hood
Комментарии
Со временем программы становятся всё сложнее и сложнее. Возникает необходимость добавлять комментарии, которые бы описывали, что делает код и почему.
Комментарии могут находиться в любом месте скрипта. Они не влияют на его выполнение, поскольку движок просто игнорирует их.
Однострочные комментарии начинаются с двойной косой черты .
Часть строки после считается комментарием. Такой комментарий может как занимать строку целиком, так и находиться после инструкции.
Как здесь:
Многострочные комментарии начинаются косой чертой со звёздочкой и заканчиваются звёздочкой с косой чертой .
Как вот здесь:
Содержимое комментария игнорируется, поэтому, если мы поместим код внутри , он не будет исполняться.
Это бывает удобно для временного отключения участка кода:
Используйте горячие клавиши!
В большинстве редакторов строку кода можно закомментировать, нажав комбинацию клавиш Ctrl+/ для однострочного комментария и что-то вроде Ctrl+Shift+/ – для многострочных комментариев (выделите кусок кода и нажмите комбинацию клавиш). В системе Mac попробуйте Cmd вместо Ctrl и Option вместо Shift.
Вложенные комментарии не поддерживаются!
Не может быть внутри .
Такой код «умрёт» с ошибкой:
Не стесняйтесь использовать комментарии в своём коде.
Комментарии увеличивают размер кода, но это не проблема. Есть множество инструментов, которые минифицируют код перед публикацией на рабочий сервер. Они убирают комментарии, так что они не содержатся в рабочих скриптах. Таким образом, комментарии никоим образом не вредят рабочему коду.
Позже в учебнике будет глава Качество кода, которая объяснит, как лучше писать комментарии.
Класс GregorianCalendar
КлассGregorianCalendar – конкретная реализация класса Calendar, отображающий обыкновенный григорианский календарь.
Метод getInstance() Calendar возвращает GregorianCalendar, который по умолчанию инициализирован текущей датой и временем, локализацией и часовым поясом. GregorianCalendar определяет 2 поля: н. э и до н. э. Это две эпохи, определяющиеся по григорианскому календарю.
Конструкторы для объектов GregorianCalendar:
Название конструктора | Краткое описание |
GregorianCalendar() | Создает GregorianCalendar, используя текущей датой и временем, локализацией и часовым поясом по умолчанию. |
GregorianCalendar(int year, int month, int date) | Создает значение GregorianCalendar с учетом заданной даты в часовом поясе и локализацией по умолчанию. |
GregorianCalendar(int year, int month, int date, int hour, int minute) | Конструирует GregorianCalendar в соответствии с заданной датой и временем в часовом поясе и локализацией по умолчанию. |
GregorianCalendar(int year, int month, int date, int hour, int minute, int second) | Конструирует GregorianCalendar в соответствии с заданной датой и временем в часовом поясе и локализацией по умолчанию. |
GregorianCalendar(Locale aLocale) | Формирует GregorianCalendar в соответствии с текущим временем в часовом поясе по умолчанию в рамках заданной локализации. |
GregorianCalendar(TimeZone zone) | Создает GregorianCalendar, основанный на текущем времени в данной зоне времени с локализацией по умолчанию. |
GregorianCalendar(TimeZone zone, Locale aLocale) | Формирует GregorianCalendar с учетом текущего времени в указанном часовом поясе и локализации. |
Полезные методы класса GregorianCalendar:
Метод | Описание |
void add(int field, int amount) | Добавляет указанное количество времени в данное временное поле в соответствии с правилами календаря. |
protected void computeFields() | Преобразует время по Гринвичу в миллисекунды до значения полей времени. |
protected void computeTime() | Преобразует значения временного поля Календаря в UTC формате в миллисекундах. |
boolean equals(Object obj) | Сравнивает этот GregorianCalendar эталонным объектом. |
int get(int field) | Получает значение для поля заданного времени. |
int getActualMaximum(int field) | Возвращает максимальное значение, которое это поле может иметь, учитывая текущую дату. |
int getActualMinimum(int field) | Возвращает минимальное значение, которое это поле может иметь, учитывая текущую дату. |
int getGreatestMinimum(int field) | Возвращает наибольшее минимальное значение для данного поля, если изменяется. |
Date getGregorianChange() | Получает изменения даты по григорианскому календарю. |
int getLeastMaximum(int field) | Возвращает минимально максимальное значение для данного поля, если изменяется. |
int getMaximum(int field) | Возвращает максимальное значение для данного поля. |
Date getTime() | Определяет текущее время в соответствии с календарем. |
long getTimeInMillis() | Получает текущее время по Календарю как длительное. |
TimeZone getTimeZone() | Возвращает часовой пояс. |
int getMinimum(int field) | Возвращает минимальное значение для данного поля. |
int hashCode() | Переопределите хэш-код. |
boolean isLeapYear(int year) | Определяет, является ли год високосным. |
void roll(int field, boolean up) | Добавление или вычитание (вверх/вниз) одной единицы времени в данном временном поле без изменений в больших полях. |
void set(int field, int value) | Устанавливает временное поле с заданным значением. |
void set(int year, int month, int date) | Задает значения для поля год, месяц и дата. |
void set(int year, int month, int date, int hour, int minute) | Задает значения для поля год, месяц, дату, час и минуту. |
void set(int year, int month, int date, int hour, int minute, int second) | Задает значения для поля год, месяц, дату, час, минуту и секунду. |
void setGregorianChange(Date date) | Устанавливает дату изменения грегорианского календаря. |
void setTime(Date date) | Устанавливает в соответствии с данным календарем текущее время с заданной датой. |
void setTimeInMillis(long millis) | Устанавливает в соответствии с данным календарем текущее время от заданного long значения. |
void setTimeZone(TimeZone value) | Задает часовой пояс со значением заданного часового пояса. |
String toString() | Возвращает строковое представление календаря. |
9) onReady()
Для инициализации страницы исторически использовалось событие window.onload, которое срабатывает после полной загрузки страницы и всех объектов на ней: счетчиков, картинок и т.п.
Событие — гораздо лучший выбор в 99% случаев. Это событие срабатывает, как только готов DOM документ, до загрузки картинок и других не влияющих на структуру документа объектов.
Это очень удобно, т.к. картинки могут загружаться долго, а обработчик может произвести необходимые изменения на странице и инициализацию интерфейсов тут же, не дожидаясь загрузки всего.
Для добавления обработчика можно использовать следующий кроссбраузерный код:
function bindReady(handler){ var called = false function ready() { // (1) if (called) return called = true handler() } if ( document.addEventListener ) { // (2) document.addEventListener( "DOMContentLoaded", function(){ ready() }, false ) } else if ( document.attachEvent ) { // (3) // (3.1) if ( document.documentElement.doScroll && window == window.top ) { function tryScroll(){ if (called) return if (!document.body) return try { document.documentElement.doScroll("left") ready() } catch(e) { setTimeout(tryScroll, 0) } } tryScroll() } // (3.2) document.attachEvent("onreadystatechange", function(){ if ( document.readyState === "complete" ) { ready() } }) } // (4) if (window.addEventListener) window.addEventListener('load', ready, false) else if (window.attachEvent) window.attachEvent('onload', ready) /* else // (4.1) window.onload=ready */ }
readyList = [] function onReady(handler) { if (!readyList.length) { bindReady(function() { for(var i=0; i<readyList.length; i++) { readyList() } }) } readyList.push(handler) }
Использование:
onReady(function() { // ... })
Подробное описание функций , и принципы их работы вы можете почерпнуть в статье Кроссбраузерное событие onDOMContentLoaded.
Цикл while()
Цикл while() называют еще циклом с предусловием. Это значит, что вы записываете в скобках после ключевого слова while некое условие, которое возвращает либо , либо . Если возвращается , цикл выполняется, если же , то нет. Синтаксис этого цикла таков:
Цикл while()
JavaScript
while( условие ){
//код цикла
операция 1;
…
операция n;
}
1 2 3 4 5 6 |
while(условие){ //код цикла операция1; … операцияn; } |
Если переводить JavaScript-код на русский язык, то смысл цикла while можно выразить такой фразой: пока (while) выполняется условие, мы будем делать некоторые операции.
Вполне возможна ситуация, когда ваш код не выполнится ни разу. Например, вам нужно подсчитать сумму чисел в заданном пользователем диапазоне. Рассмотрим вариант кода для этого с использованием полей формы типа :
Использование цикла while для подсчете чисел в заданном диапазоне
JavaScript
<form name=»numbers»>
<p>
<label for=»from»>От числа</label> <input type=»number» min=»1″ max=»50″ value=»1″ id=»from»>
</p>
<p>
<label for=»to»>До числа</label> <input type=»number» min=»1″ max=»50″ value=»5″ id=»to»>
</p>
<p><input type=»button» value=»Подсчитать» id=»countBtn»></p>
</form>
<script>
document.numbers.countBtn.onclick = countNumbers;
function countNumbers () {
let from = +document.numbers.from.value,
to = +document.numbers.to.value;
if(from > to) {
let temp = from;
from = to;
to = temp;
}
let sum = from;
while(to>from){
from++;
sum += from;
}
alert(sum);
}
</script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<form name=»numbers»> <p> <label for=»from»>Отчисла<label><input type=»number»min=»1″max=»50″value=»1″id=»from»> <p> <p> <label for=»to»>Дочисла<label><input type=»number»min=»1″max=»50″value=»5″id=»to»> <p> <p><input type=»button»value=»Подсчитать»id=»countBtn»><p> <form> <script> document.numbers.countBtn.onclick=countNumbers; functioncountNumbers(){ let from=+document.numbers.from.value, to=+document.numbers.to.value; if(from>to){ let temp=from; from=to; to=temp; } let sum=from; while(to>from){ from++; sum+=from; } alert(sum); } |
В этом примере цикл не выполнится ни разу в том случае, если значения начального и конечного чисел совпадут. Если же первое число будет больше, чем второе, мы поменяем их местами и цикл выполнится, как нужно.
Попробуйте сами:
Поскольку условие цикла while() должно вернуть либо , либо , мы можем использовать в нем диалоговое окно confirm(), которое как раз возвращает одно из этих логических значений в зависимости от выбора пользователя.
Использование диалогового окна confirm() в цикле while()
JavaScript
const prediction = ;
while (confirm(«Хотите получить предсказание»)) {
let rand = Math.floor(Math.random() * prediction.length);
alert(prediction);
}
1 2 3 4 5 6 7 8 |
constprediction=»У вас сегодня удачный день»,»Вам нужно задуматься о вашем выборе», «Сегодня вас ждет сюрприз»,»Вы — любимчик удачи»,»Попробуйте еще раз»,»Азартные игры не для вас», «Учите JavaScript — и вас ждет успех»,»Пора сделать зарядку»,»Перерыв на кофе-чай-печеньки сейчас будет кстати», «Пора выбросить мусор из квартиры»,»У вас отличный вкус»,»Нечего заглядываться на чужих жен»,»Пора поработать»; while(confirm(«Хотите получить предсказание»)){ let rand=Math.floor(Math.random()*prediction.length); alert(predictionrand); } |
Давайте немножко погадаем:
Получить предсказание
Примечание: цикл while — это тот цикл, с помощью которого лучше всего обычно получается «подвесить» браузер. Т.е. вы можете таким образом сформулировать условие в нем, что оно всегда будет возвращать , соответственно, цикл будет бесконечным и будет замедлять работу браузера.
Куда развиваться JavaScript-программисту
Изучив основы JavaScript, можно копать так глубоко, как хочется.
Хорошо освоить библиотеки и фреймворки для JavaScript — наборы готовых классов с функциями. Некоторые из них настолько мощные, что полностью меняют сценарии программирования. Для JavaScript самые популярные фреймворки и библиотеки — React, jQuery и Angular2.
Код в обеих строках делает одно и то же — скрывает элемент с идентификатором «helloDiv»
Кроме фреймворков полезно изучить надстройки над JavaScript: CoffeeScript, TypeScript и Dart. Одни надстройки сделают ваш код чище и компактнее, другие — строже.
Наконец, можно взяться за серверное программирование и Node.js. Это трендовая технология, которую используют BMW, Amazon, Apple и другие серьезные компании. Так вы расширите область своих знаний JavaScript за пределы управления веб-страницей.
Для JavaScript-программиста нет потолка развития
Хотите написать колонку для Нетологии? Читайте наши условия публикации. Чтобы быть в курсе всех новостей и читать новые статьи, присоединяйтесь к Телеграм-каналу Нетологии
Оператор typeof
Оператор возвращает тип аргумента. Это полезно, когда мы хотим обрабатывать значения различных типов по-разному или просто хотим сделать проверку.
У него есть две синтаксические формы:
- Синтаксис оператора: .
- Синтаксис функции: .
Другими словами, он работает со скобками или без скобок. Результат одинаковый.
Вызов возвращает строку с именем типа:
Последние три строки нуждаются в пояснении:
- — это встроенный объект, который предоставляет математические операции и константы. Мы рассмотрим его подробнее в главе Числа. Здесь он служит лишь примером объекта.
- Результатом вызова является . Это официально признанная ошибка в , ведущая начало с времён создания JavaScript и сохранённая для совместимости. Конечно, не является объектом. Это специальное значение с отдельным типом.
- Вызов возвращает , потому что является функцией. Мы изучим функции в следующих главах, где заодно увидим, что в JavaScript нет специального типа «функция». Функции относятся к объектному типу. Но обрабатывает их особым образом, возвращая . Так тоже повелось от создания JavaScript. Формально это неверно, но может быть удобным на практике.
Внешние переменные
У функции есть доступ к внешним переменным, например:
Функция обладает полным доступом к внешним переменным и может изменять их значение.
Например:
Внешняя переменная используется, только если внутри функции нет такой локальной.
Если одноимённая переменная объявляется внутри функции, тогда она перекрывает внешнюю. Например, в коде ниже функция использует локальную переменную . Внешняя будет проигнорирована:
Глобальные переменные
Переменные, объявленные снаружи всех функций, такие как внешняя переменная в вышеприведённом коде – называются глобальными.
Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).
Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.
Языки «над» JavaScript
Синтаксис JavaScript подходит не под все нужды. Разные люди хотят иметь разные возможности.
Это естественно, потому что проекты разные и требования к ним тоже разные.
Так, в последнее время появилось много новых языков, которые транспилируются (конвертируются) в JavaScript, прежде чем запустятся в браузере.
Современные инструменты делают транспиляцию очень быстрой и прозрачной, фактически позволяя разработчикам писать код на другом языке, автоматически преобразуя его в JavaScript «под капотом».
Примеры таких языков:
- CoffeeScript добавляет «синтаксический сахар» для JavaScript. Он вводит более короткий синтаксис, который позволяет писать чистый и лаконичный код. Обычно такое нравится Ruby-программистам.
- TypeScript концентрируется на добавлении «строгой типизации» для упрощения разработки и поддержки больших и сложных систем. Разработан Microsoft.
- Flow тоже добавляет типизацию, но иначе. Разработан Facebook.
- Dart стоит особняком, потому что имеет собственный движок, работающий вне браузера (например, в мобильных приложениях). Первоначально был предложен Google, как замена JavaScript, но на данный момент необходима его транспиляция для запуска так же, как для вышеперечисленных языков.
- Brython транспилирует Python в JavaScript, что позволяет писать приложения на чистом Python без JavaScript.
Есть и другие. Но даже если мы используем один из этих языков, мы должны знать JavaScript, чтобы действительно понимать, что мы делаем.
Цикл for…of (новинка в ES6)
Цикл появился в стандарте ES6. Предназначен он для перебора итерируемых объектов, т.е. объектов, в которых реализован метод . Этот метод ещё называют итератором. Именно его и использует цикл для перебора объектов.
Метод имеется у , , , , , и других объектов.
Пример использование цикла для посимвольного перебора строки:
// переменная, содержащая строку let str = 'Новый'; // посимвольный перебор строки for (let char of str) { console.log(char); } // в консоль будет выведено: "Н", "о", "в", "ы", "й"
Пример использование цикла для перебора коллекции DOM-элементов:
let elements = document.querySelectorAll('p'); for (let element of elements) { console.log(element); }
Пример использование цикла для перебора массива:
// массив let superHeroes = ; // перебор массива for (let value of superHeroes) { console.log(value); } // в консоль будет выведено: "Iron Man", "Thor", "Hulk"
Чем цикл for…of отличается от for…in
Первое отличие цикла от заключается в том, что он может применяться только для итерируемым объектов, т.е. объектов, в которых реализован итератор (). Цикл итератор не использует. Он предназначен для перебора любых объектов.
Второе отличие заключается в том, что цикл перебирает объект так, как это определено в итераторе. Например, в итератор реализован так, что цикл пройдёт только по значениям в массиве и не будет включать в перебор другие (не индексные) свойства. Цикл организован по-другому, он перебирает все перечисляемые свойства (имена ключей) объекта, в том числе и наследуемые.
Рассмотрим эти отличия. Для этого возьмём предыдущий пример и добавим к нему пользовательское свойство, например, и установим ему значение .
let superHeroes = ; superHeroes.hero = 'Wasp';
При использовании он переберёт все значения этого массива:
// цикл for...of for (let value of superHeroes) { console.log(value); } // в консоль будет выведено: "Iron Man", "Thor", "Hulk"
При использовании он переберёт все перечисляемые имена ключей этого объекта:
// цикл for...in for (let key in superHeroes) { console.log(key); } // в консоль будет выведено: 0, 1, 2, "hero"
Чтобы получить значение ключа по его имени можно воспользоваться квадратными скобками:
// цикл for...in for (let key in superHeroes) { console.log(superHeroes); } // в консоль будет выведено: "Iron Man", "Thor", "Hulk", "Wasp"
Самостоятельное создание итератора для объекта
Рассмотрим ещё один пример. В этом примере мы самостоятельно определим как должен итерироваться объект. Для этого создадим объект и определим ему итератор.
Создание итератора начинается с добавления к объекту специального метода. Этот метод необходимо спроектировать так, чтобы он возвращал значения последовательно (одно за другим). Название методу согласно стандарту необходимо определить с помощью символа . Итератор должен возвращать всего один метод . Этот метод в свою очередь тоже должен возвращать объект, состоящий из 2 свойств: и . Ключ — булевый. Он определяет есть ли ещё значения в последовательности ( — да, — нет). Ключ должен содержать следующее значение последовательности.
let car = { color: 'black', brand: 'Ford', // создадим итератор, используя символ () { // получим имена перечисляемых свойств объекта const keys = Object.keys(this); // создадим переменную (текущий индекс последовательности) let index = 0; return { next() { let done = index >= keys.length; let value = done ? undefined : keys; return { value, done } } } } } for (let key in car) { console.log(key + ' => ' + car); } // в консоль будет выведено: color => "black", brand => "Ford"
Константы
Чтобы объявить константную, то есть, неизменяемую переменную, используйте вместо :
Переменные, объявленные с помощью , называются «константами». Их нельзя изменить. Попытка сделать это приведёт к ошибке:
Если программист уверен, что переменная никогда не будет меняться, он может гарантировать это и наглядно донести до каждого, объявив её через .
Широко распространена практика использования констант в качестве псевдонимов для трудно запоминаемых значений, которые известны до начала исполнения скрипта.
Названия таких констант пишутся с использованием заглавных букв и подчёркивания.
Например, сделаем константы для различных цветов в «шестнадцатеричном формате»:
Преимущества:
- гораздо легче запомнить, чем .
- Гораздо легче допустить ошибку при вводе , чем при вводе .
- При чтении кода намного понятнее, чем .
Когда мы должны использовать для констант заглавные буквы, а когда называть их нормально? Давайте разберёмся и с этим.
Название «константа» просто означает, что значение переменной никогда не меняется. Но есть константы, которые известны до выполнения (например, шестнадцатеричное значение для красного цвета), а есть константы, которые вычисляются во время выполнения сценария, но не изменяются после их первоначального назначения.
Например:
Значение неизвестно до загрузки страницы, поэтому её имя записано обычными, а не прописными буквами. Но это всё ещё константа, потому что она не изменяется после назначения.
Другими словами, константы с именами, записанными заглавными буквами, используются только как псевдонимы для «жёстко закодированных» значений.
TypedAPI: клиент-сервер для TypeScript
Recovery Mode
Предлагаю вашему вниманию TypedAPI: библиотеку API клиента-сервера для проектов, в которых фронт и бэк написаны на TypeScript. Акцент делается на максимальной простоте использования. Суть такая: вы пишете API как обычный TypeScript класс с некоторыми ограничениями, потом автоматом из класса строится интерфейс, которым будет пользоваться клиентское приложение. Также генерируется некоторая служебная информация. Остается только настроить коннекторы (доступны HTTP и WebSocket). Валидацию, хранение подключений, и др. берет на себя TypedAPI. Есть поддержка событий.
Examples in Each Chapter
With our «Try it Yourself» editor, you can edit the source code and view
the result.
Example
Use the Menu
We recommend reading this tutorial, in the sequence listed in the menu.
If you have a large screen, the menu will always be present on the left.
If you have a small screen, open the menu by clicking the top menu sign ☰.
Learn by Examples
Examples are better than 1000 words. Examples are often easier to understand
than text explanations.
This tutorial supplements all explanations with clarifying «Try it Yourself» examples.
If you try all the examples, you will learn a lot about JavaScript, in a very short time!
JavaScript Examples »
Why Study JavaScript?
JavaScript is one of the 3 languages all web developers
must
learn:
1. HTML to define the content of web pages
2. CSS to specify the layout of web pages
3. JavaScript to program the behavior of web pages
This tutorial covers every version of JavaScript:
- The Original JavaScript ES1 ES2 ES3 (1997-1999)
- The First Main Revision ES5 (2009)
- The Second Revision ES6 (2015)
- The Yearly Additions (2016, 2017, 2018)
Learning Speed
In this tutorial, the learning speed is your choice.
Everything is up to you.
If you are struggling, take a break, or re-read the material.
Always make sure you understand all the «Try-it-Yourself»
examples.
The only way to become a clever programmer is to:
Practice. Practice. Practice. Code. Code. Code !
Commonly Asked Questions
- How do I get JavaScript?
- Where can I download JavaScript?
- Is JavaScript Free?
You don’t have to get or download JavaScript.
JavaScript is already running in your browser on your computer,
on your tablet, and on your smart-phone.
JavaScript is free to use for everyone.
JavaScript References
W3Schools maintains a complete JavaScript reference, including all HTML and browser objects.
The reference contains examples for all properties, methods and events, and
is continuously updated according to the latest web standards.
Complete JavaScript Reference »
w3schoolsCERTIFIED.221
❮ Home
Next ❯