JavaScript

JavaScript - объектно-ориентированный скриптовый язык программирования. Основные архитектурные черты: динамическая типизация, слабая типизация, прототипное программирование, автоматическое управление памятью. JavaScript наиболее широкое применение находит в создании клиентских сценариев (или скриптов). Это означает, что текст сценария передается на компьютер конечного пользователя и там выполняется, внося в страницу дополнительную динамику и расширяя ее возможности.

JavaScript может выполняться на стороне сервера, для этого на сервере должен быть установлен один из движков JavaScript, таких как V8, Rhino, SpiderMonkey.

На основе общедоступной документации в Microsoft был создан "перепроектированый" JavaScript - JScript.

Использование JavaScript

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

Различают две области видимости: глобальную - область видимости уровня страницы (глобальные переменные являются свойства объекта Объект Object Window HTML DOM HTML DOM), локальную - область видимости уровня функции. Переменные объявленные непосредственно в тексте сценария имеют глобальную область видимости, что делает их доступными в любом месте во всех блоках сценариев на странице. Если же переменная объявлена в теле одной из функций, то она получает локальную область видимости и может быть использована только операторами тела данной функции. Грубо говоря, интерпретатор "убивает" локальные переменные как только функция завершит свою работу. Это позволяет сэкономить массу системных ресурсов.

В JavaScript область видимости сохраняется внутри функций, а не блоков (образуемых такими операторами, как while, if и for).

Если для переменной не объявлена область видимости (не использовано объявление при помощи ключевого слова var), эта переменная становиться глобальной, даже если она используется только в области видимости внутри функции.

Ссылки.

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

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

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

Контекст JavaScript. Контекст - объект, внутри которого выполняется ваш JavaScript код. Переменная this всегда будет ссылаться на объект, внутри которого код в данный момент работает. Следует помнить, что глобальные объекты фактически являются свойствами объекта window. Это означает, что даже в глобальном контексте переменная this будет ссылаться на объект.

Методы call и apply служат для переключения контекста.

Объекты JavaScript, DOM

Объекты являются основными элементами JavaScript. В JavaScript всё является объектом, лишь за двумя исключениями — null и undefined (числовые литералы так же являются объектами). На самом базовом уровне объекты существуют как семейства свойств.

JavaScript предоставляет два основных метода создания объектов:

  • использование объектного литерала,
  • использование ключевого слова new.

Новый объект создается с помощью оператора new в паре с конструктором Object.

var myObj = new Object();

Эту запись можно упростить:

var empty = {}; // Объект без свойств
var point = { x:0, y:0 };
var circle = { x:point.x, y:point.y+1, radius:2 };
var homer = {
"name": "Homer Simpson",
"last name": "Devid",
"age": 34,
"married": true,
"email": "homer@example.com"
};

Для обращения к элементам объекта можно использовать оператор точку или propertyNameExpression (выражение JavaScript, которое определяется как строка, формирующая имя свойства, к которому происходит обращение). Например:

homer.name
homer['last name'] или можно даже так homer['las'+'t name']

Двойные кавычки можно применить, если имя свойства содержит недопустимые идентификаторы JavaScript. Если вы попытаетесь прочесть значение несуществующего свойства, вы получите undefined.

  • Конструкторы объектов:

Для создания объектов используются специально написанные для этой цели функции - конструкторы. Конструкторы могут принимать параметры, используемые для инициализации свойств объекта при создании. Например:

// конструктор объекта "Автомобиль" 
function Automobile (aVendorName, aModel) {
    this.vendor = aVendorName;
    this.model = aModel;
    this.toString = autoToStr; 
    return this;
}
// функция, выполняющая роль метода объекта "Автомобиль" 
function autoToStr() {
    return this.vendor+" "+this.model; 

В данном примере используется ключевое слово - this. this представляет собой внутренний указатель объекта. Таким образом, запись this.vendor = aVendorName; создает свойство с именем "vendor" в текущем объекте и присваивает ему значение переменной "aVendorName". После создания и инициализации всех свойств объекта, функция должна выполнить команду return this - т.е. вернуть указатель на объект в программу.

Для создания переменных объектных типов данных в JavaScript используется специальный оператор new, который записывается перед конструктором объекта. Таким образом, создание переменной объектного типа "Автомобиль" можно записать следующим образом:

// создание переменной объектного типа данных "Автомобиль" 
var myAuto = new Automobile("Toyota", "Celica");

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

  • Пример на использование двух вложенных объектов
// конструктор объекта "Двигатель" 
function Engine (cil, v) {
    this.cilCount = cil;
    this.v = v;
    return this;
}
// конструктор объекта "Автомобиль" 
function Automobile (aVendorName, aModel, nCil, V) {
    this.vendor = aVendorName;
    this.model = aModel;
    this.engine = new Engine (nCil, V);
    this.getInfo = autoInfo;

    return this;
}
function autoInfo() {
    alert ("Производитель: "+this.vendor+"\n"+
           "Модель: "+this.model+"\n"+
           "Двигатель: "+this.engine.cilCount+"цил. объем "+this.engine.v+"л.\n"); 
}

var myAuto = new Automobile("Toyota", "Celica", 6, 2.2);
myAuto.getInfo();

В JavaScript используется уникальная форма создания объектов и наследования, которая называется прототипным наследованием. Суть этого метода (в отличие от классической схемы класс-объект, знакомой большинству программистов) состоит в том, что конструктор объекта может наследовать методы от другого объекта, создавая прототип объекта — prototype, на основе которого строятся все остальные новые объекты.

Весь этот процесс облегчается наличием свойства prototype. Это свойство есть у любой функции, а раз конструктором может стать любая функция, то это свойство есть и у конструктора. Прототипы не наследуют свойства от других прототипов или других конструкторов; они наследуют их от физических объектов.

// Создание конструктора для объекта Person
function Person( name ) {
this.name = name;
}

// Добавление нового метода к объекту Person
Person.prototype.getName = function() {
return this.name;
};

// Создание нового конструктора объекта User
function User( name, password ) {
// Учтите, что здесь не поддерживается постепенная
// перегрузка-наследование, например возможность вызова
// конструктора суперкласса
this.name = name;
this.password = password;
};
// Объект User наследует все методы объекта Person
User.prototype = new Person();
// Для объекта User мы добавляет свой собственный метод
User.prototype.getPassword = function() {
return this.password;
};

Разберем строку строка User.prototype = new Person( );. User — это ссылка на функцию конструктора объекта User. При помощи выражения new Person( ) создается новый объект Person, использующий конструктор Person. Результат его работы присваивается в качестве значения свойству prototype конструктора User. Это означает, что при каждом использовании выражения new User( ), новый объект User будет обладать всеми методами, которые были у объекта Person, на тот момент, когда вы использовали выражение new Person( ).

Рассмотрим код, вызывающий конструктор без ключевого слова new, в случае чего this не будет ссылаться на создаваемый объект. Некорректный вызов Person успешно происходит, но возвращается как undefined и создаёт глобальную переменную name. Для отладки (debugging) JavaScript можно перевести его в строгий режим. Для этого наверху файла или тела функции пишется "use strict";.

function Person(name) {
    "use strict";
    this.name = name;
}
var ferdinand = Person("Евлампий");
console.log(name);
 
//undefined
//Евлампий

Операторы манипулирования объектом

Операторы манипулированием объекта:

  • for … in
  • new
  • this
  • with

Оператор for…in.

Оператор for…in присваивает переменной поочередно все свойства объекта. Для каждого свойства JavaScript выполняет указанные утверждения. Оператор for…in выглядит следующим образом:

for (variable in object) 
{   statements 
}

Следующая функция берет ее как аргумент объект и имя объекта. Затем повторяет все свойства объекта и возвращает строку, в которую внесен список имени свойства и значения.

function dump_props(obj, obj_name) {
   var result = ""
   for (var i in obj) {
      result += obj_name + "." + i + " = " + obj[i] + "<br>"
   }
   result += "<hr>"
   return result}

Для объекта car со свойствоми make и model, result выглядел бы так:

  car.make=Ford
  car.model=Mustang

Функции JavaScript

Функция объявляется при помощи ключевого слова function. Формат объявления функции имеет следующий вид:

function имя_функции ([аргументы]) {
    // тело функции
}
  • function - ключевое слово, при помощи которого объявляются функции;
  • имя_функции - уникальное в пределах сценария имя, идентифицирующее функцию. Для имен функций справедливы все те правила и требования, что и для имен переменных в JavaScript.
  • аргументы - аргументы служат для передачи функциям входных данных. При указании нескольких аргументов, они разделяются запятыми. Круглые скобки за именем функции обязательны, даже если функция не должна иметь аргументов.
  • тело функции - последовательность операторов JavaScript, выполняющих определенную задачу.

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

имя_функции ([параметры]);

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

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

Функции могут не только выполнять последовательность действий, а еще и возвращать некоторое значение, полученное в результате вычислений. Это дает возможность использовать вызовы функций в выражениях, так, как будто это обычные литеральные значения. Для того, чтобы функция возвращала значение, в ее теле должно присутствовать ключевое слово return, за которым следует возвращаемое значение. Оператор return применяется не только тогда, когда необходимо вернуть значение, но и в тех случаях, когда выполнение функции необходимо просто прервать не выполняя дальнейших действий. Для этого оператор return записывают без указания возвращаемого значения.

В примере ниже реализована функция, вычисляющая третью степень числа и возвращающая полученное значение:

<html>
	<head>
		<script type="text/javascript"> 
        <!-- 
            function cube(n) {
				var c=n*n*n; //вычисление куба числа 
				return c;    //возврат значения 
			}
        //-->
		</script>
	</head>
	<body>
		<script type="text/javascript"> 
        <!-- 
            var someNumber = 10;
			alert(2*cube(someNumber));
        //-->
		</script>
	</body>
</html>

Пример функции обратного (callback) вызова.

function doSomething(callback) {
    // ...

    // Call the callback
    callback('stuff', 'goes', 'here');
}

function foo(a, b, c) {
    // I'm the callback
    console.log(a + " " + b + " " + c);
}

doSomething(foo);

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

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

Карринг(currying) — это способ предварительного наполнения функции некоторым количеством аргументов, путем создания новой, более простой функции.

Безымянные функции: Ниже показано, как используя самовыполняемые, безымянные функции, можно скрыть от всего остального кода все переменные, которые обычно получают глобальную область видимости.

// Создание новой безымянной функции, используемой в качестве оболочки
(function(){
// Переменная, обычно имеющая глобальную область видимости
var msg = "Спасибо за визит!";
// Привязка к глобальному объекту новой функции,
window.onunload = function(){
// которая использует 'скрытую' переменную
alert( msg );
};
// Закрытие безымянной функции и ее выполнение
})();

Задержки и интервалы. DHTML анимация.

В сценариях часто возникает необходимость отложить выполнение действий на некоторое время или выполнять эти действия с заданной периодичностью. Примером может служить создание "тикающих" часов на web- странице. Для создания таких часов необходимо с периодичностью в одну секунду получать текущее время и выводить его на страницу.

Одной из наиболее мощных DHTML технологий, которую можно реализовать с помощью JavaScript и Основы работы с CSS, является анимация. В DHTML анимации нет ничего особенного – надо лишь периодически изменять одно или несколько свойств стиля одного или нескольких элементов. Чтобы, например, передвинуть изображение влево, надо постепенно увеличивать значение свойства style.left этого изображения, пока последнее не займет требуемое положение. Можно также постепенно изменять свойство style.clip для «открытия» изображения пиксел за пикселом. Никакая DHTML анимация не обходится без метода setInterval() или setTimeout() (для анимации используется также requestAnimationFrame).

  • Отложенное выполнение функции

Для отложенного выполнения функции используется метод setTimeout, имеющий следующий формат вызова:

timerId = setTimeout("код javascript", timeout);

где

  • timerId - значение, возвращаемое методом setTimeout можно использовать для отмены отложенного выполнения вункции.
  • "код javascript" - операторы JavaScript или вызов замкнутой функции
  • timeout - задержка выполнения кода в миллисекундах.

Для отмены отложенного выполнения кода используется метод clearTimeout, которому в качестве параметра передается идентификатор таймера, возвращаемый методом setTimeout:

clearTimeout(timerId);
<script>
document.body.style.background	= "blue";
setTimeout(function()	{
	document.body.style.background	= "yellow";
},	2000);
</script>
  • Периодическое выполнение функции

Для периодического выполнения функции используется метод setInterval, имеющий следующий формат вызова:

timerId = setInterval("код javascript", period);

где

  • timerId - значение, возвращаемое методом setTimeout можно использовать для отмены отложенного выполнения вункции.
  • "код javascript" - операторы JavaScript или вызов замкнутой функции
  • period - период выполнения кода в миллисекундах.

Для отмены периодического выполнения кода используется метод clearInterval, которому в качестве параметра передается идентификатор таймера, возвращаемый методом setInterval:

clearInterval(timerId);

Например, выводить сообщения каждую секунду

<script>setInterval(function () {
                alert('My message')
            }, 1000)
</script>
PQ VPS сервера в 28+ странах.