Ссылочные типы ECMAScript

Типы ссылок обычно называются классами (class).

Этот учебник будет обсуждать множество предопределенных типов ссылок в ECMAScript.

Типы ссылок

Типы ссылок обычно называются классами (class), что означает, что при обработке ссылочных значений обрабатываются объекты.

Этот учебник будет обсуждать множество предопределенных типов ссылок в ECMAScript.

С этого момента重点将讨论与已经讨论过的原始类型紧密相关的引用类型。

Примечание:С традиционной точки зрения, ECMAScript не имеет真正意义上的类. На самом деле, кроме того, что не существует класса, в ECMA-262根本没有出现“类”这个词。ECMAScript определяет “определение объекта”, логически эквивалентное классам других языков программирования.

Совет:Этот учебник будет использовать термин "объект".

Объекты создаются с помощью оператора new и имени объекта, который нужно инстанцировать. Например, следующий код создает экземпляр объекта Object:

var o = new Object();

Этот синтаксис похож на синтаксис языка Java, но когда есть более одного параметра, ECMAScript требует использования скобок. Если параметров нет, как в следующем коде, скобки могут быть опущены:

var o = new Object;

Примечание:Хотя скобки и не обязательны, лучше всего использовать их, чтобы избежать путаницы.

Совет:Мы будем более подробно обсуждать объекты и их поведение в главе о основе объектов.

Основной акцент в этом разделе будет сделан на типах с эквивалентными исходными типами.

Объект Object

Объект Object himself не очень полезен, но до того как изучить другие классы, все же стоит понять его. Porque объект Object в ECMAScript похож на java.lang.Object в Java, все объекты в ECMAScript наследуются от этого объекта, все свойства и методы объекта Object будут присутствовать в других объектах, поэтому понимание объекта Object поможет лучше понять другие объекты.

Объект Object имеет следующие свойства:

constructor
Указатель на функцию создания объекта (пинтер). Для объекта Object этот пинтер указывает на исходную функцию Object().
Prototype
Указатель на объект прототипа данного объекта. Для всех объектов он по умолчанию возвращает экземпляр объекта Object.

Объект Object также имеет несколько методов:

hasOwnProperty(property)
Определение того, есть ли у объекта определенная свойство. Нужен строковый указатель на это свойство. (Например, o.hasOwnProperty("name")).
IsPrototypeOf(object)
Определение того, является ли данный объект прототипом другого объекта.
PropertyIsEnumerable
Определение того, можно ли использовать данное свойство в операторе for...in.
ToString()
Возврат исходного строкового представления объекта. Для объекта Object ECMA-262 не определяет это значение, поэтому различные реализации ECMAScript могут иметь различные значения.
ValueOf()
Возврат наиболее подходящего исходного значения для данного объекта. Для многих объектов возвращаемое значение совпадает с значением, возвращаемым методу ToString().

Комментарий:Каждое свойство и метод, перечисленные выше, будут переопределяться другими объектами.

Объект Boolean

Объект Boolean является типом объекта, который ссылается на исходный тип Boolean.

Чтобы создать объект Boolean, достаточно передать его значение как параметр:

var oBooleanObject = new Boolean(true);

Объект Boolean переопределяет метод ValueOf() объекта Object, возвращая исходное значение, то есть true и false. Метод ToString() также переопределяется, возвращая строку "true" или "false".

К сожалению, в ECMAScript редко используются Boolean объекты, и даже если они используются, их трудно понять.

Проблемы обычно возникают при использовании Boolean объектов в Boolean выражениях. Например:

var oFalseObject = new Boolean(false);
var bResult = oFalseObject && true;	// выведет true

В этом фрагменте кода создается объект Boolean с значением false. Затем этот объект используется для выполнения операции AND с исходным значением true. Результатом AND операции false и true в Boolean вычислениях является false. Однако, в этой строке кода вычисляется oFalseObject, а не его значение false.

Как уже обсуждалось ранее, в Boolean выражениях все объекты автоматически преобразуются в true, поэтому значение oFalseObject равно true. Затем true выполняет операцию AND с true, результатом является true.

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

См.

Чтобы получить больше информации о Boolean объекте, пожалуйста, обратитесь к: Руководство по объекту Boolean в JavaScript.

Объект Number

Как вы, возможно, уже подумали, объект Number является типом объекта, который ссылается на исходный тип Number. Чтобы создать объект Number, используйте следующий код:

var oNumberObject = new Number(68);

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

Чтобы получить исходное значение Number объекта, достаточно использовать метод valueOf():

var iNumber = oNumberObject.valueOf();

Конечно, у класса Number также есть метод toString(), который был подробно рассмотрен в разделе о преобразовании типов.

Кроме стандартных методов, ингеритированных из объекта Object, объект Number имеет несколько методов,专门 предназначенных для обработки чисел.

Метод toFixed()

Метод toFixed() возвращает строковое представление числа с указанным количеством знаков после запятой. Например:

var oNumberObject = new Number(68);
alert(oNumberObject.toFixed(2));  //выводится "68.00"

В этом случае параметр метода toFixed() равен 2, что означает, что должны быть отображены два знака после запятой. Этот метод возвращает "68.00", пустые символы строки补充уются нулями. Этот метод очень полезен для приложений, работающих с деньгами.Метод toFixed() может представлять числа с 0 до 20 знаками после запятой, значения за этим диапазоном вызывают ошибку.

Метод toExponential()

Еще одним методом форматирования чисел является метод toExponential(), который возвращает строковое представление числа в виде научной нотации.

Как и метод toFixed(), метод toExponential() также имеет параметр, который указывает количество знаков после запятой, которые нужно вывести. Например:

var oNumberObject = new Number(68);
alert(oNumberObject.toExponential(1));  //выводится "6.8e+1"

Результат этого кода - "6.8e+1", как уже объяснялось, это означает 6.8x101. Вопрос в том, что если не известно, в каком формате (предполагаемом или指数ном) представлять число? В этом случае можно использовать метод toPrecision().

Метод toPrecision()

Метод toPrecision() возвращает预定形式 или指数ную форму числа в зависимости от наиболее значимой формы. У него есть параметр, который указывает на количество знаков, используемых для представления числа (без учета индекса). Например:

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(1));  //выводится "7e+1"

Задача этого кода - представить число 68 одним знаком, результат - "7e+1", а в другой форме - 70. Действительно, метод toPrecision() производит округление чисел. Но если представить 68 двумя знаками, это будет проще:

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(2));  //выводится "68"

Конечно, выводится "68", потому что это именно точное представление числа. Но что, если указать больше знаков, чем необходимо?

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(3));  //выводится "68.0"

В этом случае, toPrecision(3) эквивалентен toFixed(1), и выводится "68.0".

Методы toFixed(), toExponential() и toPrecision() выполняют операцию округления, чтобы правильно представить число с правильным количеством десятичных знаков.

Совет:Как и объект Boolean, объект Number также важен, но его использование должно быть минимальным, чтобы избежать потенциальных проблем. По возможности, используйте исходное представление чисел.

См.

Для получения дополнительной информации о числе объекта Number, пожалуйста, посетите Руководство по объекту Number в JavaScript.

Объект String

Объект String является объектным представлением типа String, который создается следующим образом:

var oStringObject = new String("hello world");

Методы valueOf() и toString() объекта String оба возвращают исходное значение типа String:

alert(oStringObject.valueOf() == oStringObject.toString());	//выводится "true"

Если запустить этот код, выводится "true", что означает, что эти значения действительно равны.

Комментарий:Объект String является одним из более сложных типов ссылок в ECMAScript. В данном разделе的重点 только на базовые функции класса String. Дополнительные продвинутые функции см. в соответствующих разделах этого руководства, или см. Руководство по объекту String в JavaScript.

Свойство length

У объекта String есть свойство length, которое является количеством символов в строке:

var oStringObject = new String("hello world");
alert(oStringObject.length);	//выводится "11"

Этот пример выводит "11", что означает количество символов в "hello world". Обратите внимание, что даже если строка содержит двухбайтовые символы (в сравнении с ASCII-символами, которые занимают всего один байт), каждый символ считается отдельным.

Методы charAt() и charCodeAt()

Объект String также имеет множество методов.

Сначала, методы charAt() и charCodeAt() доступа к отдельным символам строки. У обоих методов есть один параметр, который указывает на положение символа для обработки.

Метод charAt() возвращает строку, содержащую символ по указанному положению:

var oStringObject = new String("hello world");
alert(oStringObject.charAt(1));	//выводится "e"

В строке "hello world" символ на позиции 1 является "e". В разделе "ECMAScript базовые типы" мы говорили, что позиция первого символа составляет 0, позиция второго символа составляет 1 и так далее. Поэтому вызов charAt(1) возвращает "e".

Если вы хотите получить не символ, а код символа, можно вызвать метод charCodeAt():

var oStringObject = new String("hello world");
alert(oStringObject.charCodeAt(1));	//вывод "101"

Этот пример выводит "101", то есть код символа "e" в нижнем регистре.

Метод concat()

Далее идет метод concat(), который используется для подключения одного или нескольких строк к исходному значению String объекта. Этот метод возвращает исходное значение String, не изменяя исходный String объект:

var oStringObject = new String("hello ");
var sResult = oStringObject.concat("world");
alert(sResult);		//вывод "hello world"
alert(oStringObject);	//вывод "hello "

В этом фрагменте кода concat() метод возвращает "hello world", а String объект сохраняет "hello ". Из-за этой причины наиболее часто используется знак plus (+) для подключения строк, так как это логически отражает истинное поведение:

var oStringObject = new String("hello ");
var sResult = oStringObject + "world";
alert(sResult);		//вывод "hello world"
alert(oStringObject);	//вывод "hello "

Методы indexOf() и lastIndexOf()

До сих пор обсуждались методы для подключения строк, доступа к отдельным символам в строке. Однако, если вы не можете определить, действительно ли в строке существует определенный символ, какие методы следует вызвать? В этом случае можно вызвать методы indexOf() и lastIndexOf().

Методы indexOf() и lastIndexOf() возвращают положение指定анной подстроки в другом字符串е. Если подстрока не найдена, возвращается -1.

Различие между этими методами заключается в том, что метод indexOf() начинает поиск подстроки от начала строки (позиция 0), а метод lastIndexOf() начинает поиск от конца строки. Например:

var oStringObject = new String("hello world!");
alert(oStringObject.indexOf("o"));		//вывод "4"
alert(oStringObject.lastIndexOf("o"));		//вывод "7"

Здесь, первая "o" строки出现在 позиции 4, то есть "hello"; последняя "o"出现在 позиции 7, то есть "world". Если в строке只有一个 "o", то методы indexOf() и lastIndexOf() возвращают одну и ту же позицию.

Метод localeCompare()

Следующий метод - localeCompare(), который выполняет сортировку строк. Этот метод имеет один параметр - строку для сравнения, и возвращает одно из следующих трех значений:

  • Если строка String расположена перед строкой в параметре по алфавитному порядку, возвращается отрицательное значение.
  • Если строка String равна строке в параметре, возвращается 0
  • Если строка String расположена после строки в параметре по алфавитному порядку, возвращается положительное значение.

Комментарий:Если возвращается отрицательное значение, то наиболее часто встречается -1, но на самом деле возвращаемое значение зависит от реализации. Если возвращается положительное значение, то также наиболее часто встречается 1, но на самом деле возвращаемое значение зависит от реализации.

Пример приведен ниже:

var oStringObject = new String("yellow");
alert(oStringObject.localeCompare("brick"));		//вывод "1"
alert(oStringObject.localeCompare("yellow"));		//вывод "0"
alert(oStringObject.localeCompare("zoo"));		//вывод "-1"

В этом коде строка "yellow" сравнивается с тремя значениями, namely "brick", "yellow" и "zoo". Поскольку они расположены в алфавитном порядке, "yellow" стоит после "brick", поэтому метод localeCompare() возвращает 1; "yellow" равен "yellow", поэтому метод localeCompare() возвращает 0; "zoo" стоит после "yellow", метод localeCompare() возвращает -1. Еще раз подчеркиваю, поскольку возвращаемое значение зависит от реализации, лучше вызывать метод localeCompare() следующим образом:

var oStringObject1 = new String("yellow");
var oStringObject2 = new String("brick");
var iResult = oStringObject1.localeCompare(oStringObject2);
if(iResult < 0) {
  alert(oStringObject1 + " приходит перед " + oStringObject2);
}
  alert(oStringObject1 + " приходит после " + oStringObject2);
}
  alert("Два строки равны");
}

Используя эту структуру, можно обеспечить правильную работу этого кода во всех реализациях.

Уникальность метода localeCompare() заключается в том, что область (locale, что означает страну/регион и язык) точно определяет способ работы этого метода. В США английский язык является стандартным языком реализации ECMAScript, и localeCompare() является чувствительным к регистру, где заглавные буквы следуют за строчными в алфавитном порядке. Однако, в других регионах ситуация может быть иной.

slice() и substring()

ECMAScript предоставляет два метода для создания строковых значений из подстроки, это slice() и substring(). Оба метода возвращают подстроку строки, которую необходимо обработать, и принимают один или два параметра. Первый параметр - это начальная позиция подстроки, которую нужно получить, а второй параметр (если он используется) - это позиция终止а подстроки перед终止ом (т.е., символ в позиции终止а не включается в возвращаемое значение). Если параметр не указан, позиция终止а по умолчанию равна длине строки.

Как и метод concat(), методы slice() и substring() не изменяют значение объекта String. Они возвращают только исходное значение строки, сохраняя объект String неизменным.

var oStringObject = new String("hello world");
alert(oStringObject.slice("3")); // вывод "lo world"
alert(oStringObject.substring("3")); // вывод "lo world"
alert(oStringObject.slice("3", "7")); // вывод "lo w"
alert(oStringObject.substring("3", "7")); // вывод "lo w"

В этом примере использование slice() и substring() одинаково, и значения возвращаемые ими также одинаковы. Когда используется только параметр 3, обе функции возвращают "lo world", потому что второй "l" в "hello" находится на позиции 3. Когда используются два параметра "3" и "7", обе функции возвращают "lo w" (буква "o" в "world" находится на позиции 7, поэтому она не включена в результат).

Почему есть два метода с совершенно одинаковыми функциями? На самом деле, эти два метода не совершенно одинаковы, но только при отрицательных параметрах они обрабатывают параметры по-разному.

Для отрицательных параметров метод slice() добавляет параметр к длине строки, а метод substring() рассматривает его как 0 (то есть его игнорирует). Например:

var oStringObject = new String("hello world");
alert(oStringObject.slice("-3")); // вывод "rld"
alert(oStringObject.substring("-3")); // вывод "hello world"
alert(oStringObject.slice("3, -4")); // вывод "lo w"
alert(oStringObject.substring("3, -4")); // вывод "hel"

Таким образом можно看出 основные различия между методами slice() и substring().

Когда используется только параметр -3, функция slice() возвращает "rld", а функция substring() возвращает "hello world". Это потому, что для строки "hello world", slice("-3") будет преобразовано в slice("8"), а substring("-3") будет преобразовано в substring("0").

Таким же образом, при использовании параметров 3 и -4, различия также очевидны. slice() будет преобразован в slice(3, 7), как и в предыдущем примере, возвращая "lo w". А метод substring() интерпретирует два параметра как substring(3, 0), что на самом деле означает substring(0, 3), так как substring() всегда использует меньшее число в качестве начальной позиции, а большее число в качестве позиции завершения. Таким образом, substring("3, -4") возвращает "hel". Последняя строка кода используется для объяснения, как использовать эти методы.

toLowerCase(), toLocaleLowerCase(), toUpperCase() и toLocaleUpperCase()

Следующие методы, которые мы будем обсуждать, касаются преобразования大小写. Есть 4 метода для выполнения преобразования大小写:

  • toLowerCase()
  • toLocaleLowerCase()
  • toUpperCase()
  • toLocaleUpperCase()

Как следует из их названий, первые два метода используются для преобразования строки в полужирный шрифт, а последние два метода используются для преобразования строки в полужирный шрифт.

Методы toLowerCase() и toUpperCase() являются оригинальными и реализованы по аналогии с методами java.lang.String.

Методы toLocaleLowerCase() и toLocaleUpperCase() реализованы на основе специфичных для региона реализаций (как и метод localeCompare()). В многих регионах специфичные для региона методы идентичны общим методам. Однако, у некоторых языков есть специфичные правила для преобразования大小写 Unicode (например, турецкий), поэтому необходимо использовать специфичные для региона методы для правильного преобразования.

var oStringObject = new String("Hello World");
alert(oStringObject.toLocaleUpperCase()); // вывести "HELLO WORLD"
alert(oStringObject.toUpperCase()); // вывести "HELLO WORLD"
alert(oStringObject.toLocaleLowerCase()); // вывести "hello world"
alert(oStringObject.toLowerCase()); // Вывод "hello world"

В этом коде функция toUpperCase() и функция toLocaleUpperCase() выводят "HELLO WORLD", а функции toLowerCase() и toLocaleLowerCase() выводят "hello world". В общем, если не известно, в каком кодировании выполняется язык, безопаснее использовать методы, специфичные для региона.

Совет:Запомните, все свойства и методы объекта String можно использовать и с исходными значениями String, потому что они являются псевдообъектами.

Оператор instanceof

При использовании оператора typeof с переменными, хранящими значения типа引用, может возникнуть проблема: независимо от того, какой тип объекта хранится, он всегда возвращает "object". ECMAScript ввел другой оператор instanceof для решения этой проблемы.

Оператор instanceof похож на оператор typeof и используется для определения типа объекта, с которым работают. В отличие от метода typeof, метод instanceof требует, чтобы разработчик явно подтвердил, что объект является определенным типом. Например:

var oStringObject = new String("hello world");
alert(oStringObject instanceof String); // Вывод "true"

Этот код спрашивает: "Является ли переменная oStringObject примером объекта String?" oStringObject действительно является примером объекта String, поэтому результат "true". Хотя он не так гибок, как метод typeof, метод instanceof все же очень полезен в том случае, если метод typeof возвращает "object".