Типы

JavaScript предоставляет несколько встроенных типов данных. В дополнение к ним на этой странице рассматриваются виртуальные типы, такие как селекторы, расширенные псевдо-типы, как, например, события и все остальное о функциях.

Вы можете увидеть в действии все рассматриваемые ниже примеры просто копируя их в консоль Firebug (примечание: Firebug требует наличия Firefox).

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

Например:

 var x = ""
 if ( x )
   console.log("x defaulted to true")
 else
   console.log("x defaulted to false")

В этом случае будет напечатано «x defaulted to false».

Для того, чтобы не делать примеры громоздкими, используется оператор отрицания:

 !x // истина

Перейдем непосредственно к типам.

Содержание

Строка

 "I'm a String in JavaScript!"
 'So am I!'

Строка в JavaScript — неизменяемый объект, который может содержать как ни одного, так и множество символов.

Тип данных строки — «string».

 typeof "some string"; // "string"

Кавычки

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

 "You make 'me' sad."
 'Holy "cranking" moses!'
 "<a href=\"home\">Home</a>"

Встроенные методы

Строка в JavaScript имеет некоторые встроенные методы манипулирования с ней, результат — это всегда новая строка или что-то другое (например, split возвращает array).

 "hello".charAt(0) // "h"
 "hello".toUpperCase() // "HELLO"
 "Hello".toLowerCase() // "hello"
 "hello".replace(/e|o/g, "x") // "hxllx"
 "1,2,3".split(",") // ["1", "2", "3"]

Длина строки

Все строки имеют свойство длины.

 "Hello".length // 5
 "".length // 0

Логическое значение по умолчанию

Значение пустой строки по умолчанию всегда false:

 !"" // true
 !"hello" // false
 !"true" // false
 !new Boolean(false) // false

Число

 12
 3.543

Числа в JavaScript представляют собой 64-битные значения двойной точности формата IEEE 754. Они такие же неизменяемые, как и строки. Доступны С-подобные операторы для работы с числами (+, -, *, /, %, =, +=, -=, *=, /=, ++, –).

Тип данных числа — «number».

 typeof 12 // "number"
 typeof 3.543 // "number"

Логическое значение по умолчанию

Если это 0, то значение по умолчанию false:

 !0 // true
 !1 // false
 !-1 // false

Поскольку числа реализованы как значения двойной точности, то следующий результат является верным:

 0.1 + 0.2 // 0.30000000000000004

Объект Math

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

 Math.PI // 3.141592653589793
 Math.cos(Math.PI) // -1

Анализ чисел

parseInt и parseFloat помогают анализировать числа и преобразовывать строки в числа. Если система исчисления не указана, они делают некоторое неявное преобразование:

 parseInt("123") = 123 (неявное десятичное)
 parseInt("010") = 8 (неявное восьмеричное)
 parseInt("0xCAFE") = 51966 (неявное шестнадцатеричное)
 parseInt("010", 10) = 10 (заданное десятичное)
 parseInt("11", 2) = 3 (заданное двоичное)
 parseFloat("10.10") = 10.1

Конвертация чисел в строки

После добавления чисел к строке результат всегда является строкой. Оператор идентичен, поэтому будьте осторожны: если Вы хотите сложить числа и потом добавить их к строке, то вычисления необходимо взять в круглые скобки:

 "" + 1 + 2; // "12"
 "" + (1 + 2); // "3"
 "" + 0.0000001; // "1e-7"
 parseInt(0.0000001); // 1 (!)

Или используйте класс String в  javascript, который пытается проанализировать значение как строку:

 String(1) + String(2); //"12"
 String(1 + 2); //"3"

Неопределенности и бесконечности

Анализ чего-то, что не является числом вовзвращает неопределенность (NaN). isNaN может помочь обнаружить подобный случай:

 parseInt("hello", 10) // NaN
 isNaN(parseInt("hello", 10)) // true

Деление на ноль возвращает бесконечность:

 1 / 0 // Infinity

Как неопределенность (NaN), так и бесконечность (Infinity) имеют тип «number»:

 typeof NaN // "number"
 typeof Infinity // "number"

Помните, что неопределенности сравниваются довольно странным способом:

 NaN == NaN // false (!)

Но:

 Infinity == Infinity // true

Integer

Integer — чистый тип числа. Всегда, когда явно указан, показывает, что ожидается non-floating-point число.

Float

Float — чистый тип числа, также как и Integer, но всегда, когда явно указан, показывает, что ожидается floating-point число.

Логическое значение

Логическое значение в JavaScript может быть либо true либо false:

 if ( true ) console.log("always!")
 if ( false ) console.log("never!")

Когда опция указывается как логическое значение, то это зачастую выглядит следующим образом:

$("...").somePlugin({
  hideOnStartup: true,
  onlyOnce: false
});

Объект

Все в JavaScript представляет собой объект. Самый простой способ создать объект — использовать символ объекта:

 var x = {};
 var y = {
   name: "Pete",
   age: 15
 };

Тип данных объекта — «object»:

 typeof {} // "object"

Точка

Вы можете указывать и читать свойства объекта используя точку:

 y.name // "Pete"
 y.age // 15
 x.name = y.name + " Pan" // "Pete Pan"
 x.age = y.age + 1 // 16

Массив

Также можно указывать и читать свойства объекта используя массив, что позволяет Вам динамически выбирать свойство:

 var operations = {
   increase: "++",
   decrease: "--"
 }
 var operation = "increase";
 operations[operation] // "++";
 operations["multiply"] = "*"; // "*"

Итерация

Производить операции над объектами проще всего в цикле for:

var obj = {
  name: "Pete",
  age: 15
};
for(key in obj) {
 alert("key is "+[key]+", value is "+obj[key]);
}

Следует отметить, что цикл может быть испорчен путем расширения Object.prototype (обратитесь к статье  Object.prototype), поэтому будьте внимательны при использовании других библиотек.

jQuery предоставляет функцию each для операций над свойствами объектов а также над элементами массивов:

 jQuery.each(obj, function(key, value) {
   console.log("key", key, "value", value);
 });

Недостатком является то, что функция вызывается в контексте каждого значения, поэтому Вы теряете контекст Вашего собственного объекта. Более подробно об этом ниже в разделе «Функции».

Логическое значение по умолчанию

Независимо от того, есть-ли у объекта свойства или нет, он никогда по умолчанию не является false:

 !{} // false

Прототип

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

 var form = $("#myform");
 form.clearForm; // undefined
 form.fn.clearForm = function() {
   return this.find(":input").each(function() {
     this.value = "";
   }).end();
 };
 form.clearForm() // работает для всех экземпляров объектов jQuery, так
как новый метод был добавлен в прототип

Опции

Опции в jQuery являются чистыми объектами JavaScript. Всякий раз, когда Опции упоминаются как тип, объект и также все его свойства необязательны. Бывают исключения, когда требуется как минимум одна опция. Наиболее примечательный способ использования Опций jQuery — это метод AJAX.

Почти все дополнения в jQuery предоставляют API на основе Опций: Они работают безо всякой настройки, но позволяют при этом пользователю настроить все, что необходимо. Давайте рассмотрим пример из дополнения форм, который дает возможность отправить форму через AJAX воспользовавшись всего лишь одной простой строчкой кода:

 $("#myform").ajaxForm();

В этом режиме используется атрибут формы «действие» как AJAX-ссылка и атрибут «метод» для определения, какой из двух методов использовать: GET или POST. Можно переназначить значения по умолчанию указав соответствующие опции:

 $("#myform").ajaxForm({
   url: "mypage.php",
   type: "POST"
 });

Массив

Массивы в JavaScript — это изменяемые списки с некоторыми встроенными методами. Объявить массив можно используя символ массива:

 var x = [];
 var y = [1, 2, 3];

Тип массива — «object»:

 typeof []; // "object"
 typeof [1, 2, 3]; // "object"

Чтение и запись элементов массива возможно при использовании квадратных скобок:

 x[0] = 1;
 y[2] // 3

Итерация

Массив имеет полезное для итераций свойство длины:

 for (var i = 0; i < a.length; i++) {
   // Do something with a[i]
 }

Если критична производительность, то чтение свойства длины массива единожды может повысить скорость работы:

 for (var i = 0, j = a.length; i < j; i++) {
   // Do something with a[i]
 }

Еще одна вариация определяет переменную, которая заполняется для каждой итерации,  удаляя знак массива из тела цикла. Этот метод не работает в случае если массив содержит 0 или пустые строки!

 for (var i = 0, item; item = a[i]; i++) {
   // Do something with item
 }

jQuery предоставляет функцию each для операций над свойствами объектов а также над элементами массивов:

 var x = [1, 2, 3];
 jQuery.each(x, function(index, value) {
   console.log("index", index, "value", value);
 });

Недостатком является то, что функция вызывается в контексте каждого значения, поэтому Вы теряете контекст Вашего собственного объекта. Более подробно об этом ниже в разделе «Функции».

Свойство длины также можно использовать для добавления элементов в конец массива. Это эквивалентно использованию метода push:

 var x = [];
 x.push(1);
 x[x.length] = 2;
 x // 1, 2

Вы можете ознакомиться с обеими вариациями изучив исходный код библиотеки JavaScript.

Существуют также другие встроенные методы такие как reverse, join, shift, unshift, pop, slice, splice и sort:

 var x = [0, 3, 1, 2];
 x.reverse() // [2, 1, 3, 0]
 x.join(" – ") // "2 - 1 - 3 - 0"
 x.pop() // [2, 1, 3]
 x.unshift(-1) // [-1, 2, 1, 3]
 x.shift() // [2, 1, 3]
 x.sort() // [1, 2, 3]
 x.splice(1, 2) // [2, 3]

Примечание: метод .unshift() не возвращает свойство длины в Internet Explorer.

Логическое значение по умолчанию

Независимо от того, есть-ли в массиве элементы или нет, он никогда по умолчанию не является false:

 ![] // false

Массив <Тип>

В jQuery API Вы часто можете видеть обозначение  Массив<Тип>:

dragPrevention    Array<String>

Это означает, что метод ожидет в качестве аргумента массив с элементами указанного типа. Данная структура была позаимствована из Java 5 (или шаблонов C++).

Тип Map

Тип map используется функцией AJAX для сохранения данных запроса. Тип может представлять собой строку, массив элементов, объект jQuery с элементами формы или парами ключ/значение.

В последнем случае появляется возможность назначить множество значений одному ключу путем присваивания ему массива значений.

{'key[]':['valuea','valueb']}

преобразуется на стороне сервера (на РНР):

$_REQUEST['key'][0]="valuea";
$_REQUEST['key'][1]="valueb";

на Rails или Merb:

 params[:key] = ["valuea", "valueb"]

Функция

Функция в JavaScript может как иметь имя, так и быть безымянной. Безымянная функция может быть назначена переменной или передана методу.

function named() {}
var handler = function() {}

Множество безымянных функций можно видеть в коде jQuery:

 $(document).ready(function() {});
 $("a").click(function() {});
 $.ajax({
   url: "someurl.php",
   success: function() {}
 });

Тип функции — «function».

Аргументы

Внутри функции всегда доступна специальная переменная «arguments». Переменная подобна массиву, таким образом она имеет свойство длины, но не имеет встроенных методов, которые присущи массиву. Элементы псевдо-массива являются аргументом вызова функции.

function log(x) {
  console.log(typeof x, arguments.length);
}
log(); // "undefined", 0
log(1); // "number", 1
log("1", "2", "3"); // "string", 3

Объект аргументов также имеет свойство «callee», что ссылается на функцию в пределах которой Вы находитесь. Например:

 var awesome = function() { return arguments.callee }
 awesome() == awesome // true

Контекст, Call и Apply

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

Все обработчики событий в jQuery вызываются с управляющим элементом в качестве контекста.

$(document).ready(function() {
  // ссылается на window.document
});
$("a").click(function() {
  // ссылается на тег а
});

Вы можете указать контекст для вызова функции используя встроенные методы call и apply. Различие между этими двумя методами заключаются в способе передачи аргументов. Call передает все аргументы в качестве аргументов функции, тогда как apply принимает массив в качестве аргументов.

function scope() {
  console.log(this, arguments.length);
}
scope() // window, 0
scope.call("foobar", [1,2]); // "foobar", 1
scope.apply("foobar", [1,2]); // "foobar", 2

Пространство функции

В JavaScript переменные, которые определены внутри функции,  доступны только в пространстве самой функции. Рассмотрим следующий пример:

 // global
 var x = 0;
 (function() {
   // private
   var x = 1;
   console.log(x); // 1
 })();
 console.log(x); // 0

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

Привязки

Привязки создаются всякий раз, когда внутри функции необходимо получить доступ к переменной, объявленной вне текущего пространства функции. В приведенном примере ниже переменная counter видима в пределах функций create, increment и print, но не за их пределами.

function create() {
  var counter = 0;
  return {
    increment: function() {
      counter++;
    },
    print: function() {
      console.log(counter);
    }
  }
}
var c = create();
c.increment();
c.print(); // 1

Модель позволяет создавать объекты с помощью методов, которые оперируют над данными, не видимыми извне. Основа объектно-ориентированного программирования.

Модель proxy

Сочетание всех вышеизложенных знаний дает Вам, как разработчику JavaScript, достаточно много возможностей. Одним из способов этого сочетания является внедрение модели proxy в JavaScript, реализуя тем самым основы аспектно-ориентированного программирования (АОР):

(function() {
  // log all calls to setArray
  var proxied = jQuery.fn.setArray;
  jQuery.fn.setArray = function() {
    console.log(this, arguments);
    return proxied.apply(this, arguments);
  };
})();

Структура выше заключает свой код в функцию для того, чтобы скрыть «проксируемую» переменную. Предоставляемый jQuery метод setArray сохраняется в привязке и перезаписывается. Прокси в дальнейшем регистрирует все вызовы к методу и передает их подлинному методу. Использование apply(this, arguments) дает гарантию, что вызывающий не заметит разницы между подлинным и проксируемым методом.

Обратный вызов

Обратный вызов представляет собой функцию JavaScript, переданную какому-либо методу в качестве аргумента или опции. Некоторые обратные вызовы являются лишь событиями, вызванными для того, чтобы дать пользователю возможность отреагировать в случае наступления соответствующего состояния. Система событий jQuery повсеместно использует подобные обратные вызовы:

 $("body").click(function(event) {
   console.log("clicked: " + event.target);
 });

Большинство обратных вызовов могут иметь аргументы и пространство. В примере выше обратный вызов вызывается лишь с одним аргументом — Событием. Пространство вызова установлено в соответствии с управляющим элементом (в примере выше это document.body).

Некоторые вызовы обязаны возвращать что-либо, другие — по желанию разработчика.

Для предотвращения отправки формы обработчик события отправки может возвращать false:

 $("#myform").submit(function() {
   return false;
 });

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

Селектор

Селектор используется в jQuery для выборки элементов DOM из документа DOM. Документ в большинстве случаев является документом DOM, присутствующим во всех браузерах, но также может представлять собой документ XML полученный посредством AJAX.

Селекторы представляют собой набор CSS кода и некоторые пользовательские дополнения. Селекторы XPath доступны в виде дополнения (плагина).

Все доступные в jQuery селекторы показаны в разделе API селекторов.

Существует огромное количество дополнений, использующих селекторы jQuery в других направлениях. Дополнения, которые занимаются проверкой данных, принимают селектор для определения необходимости введения значения или отсутствия таковой:

 emailrules: {
   required: "#email:filled"
 }

В данном случае флажок с именем «emailrules» будет доступен только при условии, что пользователь ввел адрес электронной почты в соответствующее поле, которое проверяется селектором с именем «:filled».

Если селектор указан как тип аргумента, то он принимает все, что может принять конструктор jQuery (Строки, Элементы, Списки элементов).

Событие

Система событий в jQuery соответствует стандартам W3C. Объект события гарантированно будет передан обработчику события (нет необходимости для проверки window.event).

Для работы с событиями существуют также методы stopPropagation() и preventDefault().

Все свойства задокументированы и сопровождаются примерами в разделе Событие.

Элемент

Элемент в Объектной Модели Документа (DOM) обладает атрибутами, текстом и дочерними объектами. Он предоставляет методы для анализа «родителей» и «детей» а также для получения доступа к их атрибутам. Из-за множества недостатков спецификации и реализации DOM API эти методы достаточно сложно использовать. jQuery является оберткой поверх этих элементов, помогая взаимодействовать с DOM. Тем не менее, достаточно часто придется работать напрямую с элементами DOM или с методами, которые принимают элементы DOM в качестве аргументов. Всякий раз, например, когда Вы используете метод each, контекст вызываемой функции является элементом DOM. Это также относится к обработчикам событий. Некоторые свойства элементов DOM полностью совпадают в разных браузерах. Рассмотрим пример простой on-blur проверки:

$(":text").blur(function() {
  if(!this.value) {
   alert("Please enter some text!");
  }
});

Вместо this.value можно написать  $(this).val() для доступа к значению поля input посредством jQuery, но в этом случае Вы не получите ничего.

Retrieved from «http://docs.jquery.com/Types«