Что такое литерал в javascript
Перейти к содержимому

Что такое литерал в javascript

  • автор:

15. Текст: строковые литералы в JavaScript

Что такое текст, думаю, знают все. А что такое строка в JavaScript? Строка в JavaScript – это последовательность 16-битных значений, каждое значение является, в большинстве случаев, символом Юникода. Длина строки – количество 16-битных значений. Пустая строка – строка, длина которой равна 0.

Строковые литералы – символы, заключенные в одинарные или двойные кавычки. Для понимания: примеры строковых литералов.

"" /* Пустая строка */
'' /* Пустая строка */
' ' /* Пробел */
'Какая-то фраза'
"7199.12"
"don't"
"Здесь\nТри\nСтроки"

В строковых литералах (в языке JavaScript) есть небольшая проблема, доставляющая неудобство. Строковые литералы должны быть записаны на одной строке и если вы разобьете фразу на две строки, то возникнет ошибка. Но разработчики JavaScript’a решили проблему так: после каждой строки ставить обратный слэш (\). Но здесь нужно быть очень внимательным! Если после обратного слэша есть хоть какой-то символ, даже пробел, то это получается опять ошибка. Далее пример:

/* Здесь все отлично */
"Раз строка\
Два строка\
Три строка"
/* А здесь после "Раз строка" есть пробел, который можно заметить, выделив этот код */
"Раз строка\
Два строка\
Три строка"

Как подсчитать длину строки?

Свойство length можно использовать, чтобы определить длину строки. Далее пример:

var str = "двадцатичетырехбуквенный"; /* => 24 */
document.write(str.length);

Литерал объекта

Самый простой способ создать объект заключается во включении в программу литерала объекта.
Литерал объекта — это заключенный в фигурные скобки список свойств (пар имя/значение), разделенных запятыми.

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

var empty = <>; // Объ­ект без свойств var point = < x:0, y:0 >; // Два свой­ст­ва var point2 = < x:point.x, y:point.y+1 >; // Бо­лее слож­ные зна­че­ния var book = < "main title": "Ja­va­Script", // Име­на свойств с про­бе­ла­ми 'sub-title': "The Definitive Guide", // и де­фи­са­ми, по­это­му ис­поль­зу­ют­ся стро­ко­вые ли­те­ра­лы "for": "all audiences", // for - за­ре­зер­ви­ро­ван­ное сло­во, по­это­му в ка­выч­ках author: < // Зна­че­ни­ем это­го свой­ст­ва яв­ля­ет­ся firstname: "David", // объ­ект. Об­ра­ти­те вни­ма­ние, что surname: "Flanagan" // име­на этих свойств без ка­вы­чек. > >; 

В ECMAScript 5 последняя запятая, следующая за последним свойством в литерале объекта, игнорируется. В боль- шинстве реализаций ECMAScript 3 завершающие запятые также игнорируются, но IE интерпретирует их наличие как ошибку.

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

results matching » «

No results matching » «

Урок №3: литералы в JavaScript

Литералы в JavaScript

Литералы — это фиксированные данные с которыми будет работать программа, иными словами литералы являются значениями в JavaScript (также стоит заметить, что литералы являются важным фрагментом любого языка программирования, т.к. невозможно написать программу без них). Литералы включаются в текст программы и не могут быть изменены. Для лучшего понимания рассмотрим пример:

var numb = 14;
var flower = «Роза»;

Итак, var — это оператор, который назначает переменные, numb и flower — это название переменных, а 14 и «Роза» — это и есть наши литералы. Существуют целочисленные, строковые, логические, объектные, массивные и вещественные литералы. Рассмотрим каждый из них более подробно.

Литералы целого типа

Целые числа могут быть:

  • десятеричными (от 0 до 9), например: 10, +7, -129;
  • 16-теричными (от 0 до F), например: 0x22, 0x3F, 0xB5 , обратите внимание, именно символы 0x, которые находятся вплотную перед числом, указывают, что число будет 16-теричное;
  • 8-миричными (от 0 до 7), например 033, 0521, 021 , обратите внимание, перед числами стоит 0, именно он указывает, что числа являются 8-миричными.

Литералы с точкой

Это дробные числа, которые отделяются точкой, такие как: 75.25, -21.34, +33.03 . Так как в JavaScript умножение и 10 заменяется на символ «e» или «E», то число 34.11*10-5, можно записать в таком виде: 34.11E-5. Литералы с плавающей точкой состоят минимум из одной цифры и десятичной точки или экспонента — «e» или «E».

Вот еще несколько литералов с плавающей точкой: 3.112, -3.2E62, .3e14, 3E-62

Литералы массива

Под литералом массива понимают список, в котором имеется от нуля до нескольких выражений, каждое из которых является элементом массива, такие элементы заключаются в квадратные скобки — [] . Массив – это вид данных, который хранит пронумерованные значения. Каждое такое значение назыввают элементом массива, а число, с которым связывается данный элемент, является его индексом.

Мы еще вернемся к массивам на следующих уроках и разберем их более подробно.

Строковые литералы

Строковые литералы, как правило являются текстом. Состоят они из нуля или более последовательных символов, которые с двух сторон заключаются в одинарные (‘) или двойные («) кавычки. Строка должна быть выделена только одним типом кавычек, так что сразу определитесь для себя, какие вы будете использовать. Примеры строковых литералов:

«Splash»
‘Splash’
«1234»
«первая строка, перенос \n вторая строка»

В строчных литералах, помимо стандартных символов, можно использовать специальные (см. таблицу).

Символ Значение
\b Имитирует Backspace
\f Form feed/прогон страницы
\n New line/перенос на новую строку
\r Carriage return/возврат каретки
\t Tab/табуляция
\’ Апостроф или одинарная кавычка
Двойная кавычка
\\ Обратный слэш (\)
\XXX Символ из набора Latin-1, специфицированный тремя 8-меричными цифрами XXX (от 0 до 377). Например, \251 это восьмеричная последовательность для символа copyright.
\xXX Символ из набора Latin-1, специфицированный двумя 16-ричными цифрами XX (от 00 до FF). Например, \xA9 это 16-ричная последовательность для символа copyright.
\uXXXX Символ Unicode, специфицированный четырьмя 16-ричными цифрами XXXX. Например, \u00A9 это Unicode-последовательность для символа copyright.

Логические литералы

Логические литералы еще называют литералами булевого типа (Bollean). Здесь все просто, данный литерал имеет всего два значения: true (истина) и false (ложь). Эти два зарезервированных значения не являются ключевыми, однако, они также не могут быть использованны в качестве идентификатора.

И в заключении обратите внимание на обобщающий пример с различными литералами:

7 // целое число
18.2 // число с плавающей точкой
«текст» // строка текста
‘еще текст’ // вторая строка
true // логическое значение (булево)
null // пустой объект
undefined // неопределенное значение

На следующем уроке подробно рассмотрим переменные и константы в JavaScript: Переменные и Константы

GoodDayTodayOkey / js-pattrens-literals-&-constructors.md

Можно сказать, что литерал — это чистое значение, которое встречается в приложении.

Один из способов создать объект — с помощью литерала:

var user = <>; // создали пустой объект user.name = 'admin'; user.getName = function ()

Однако для создания объектов лучше использовать литерал, который сразу определяет его структуру (если, конечно, эта структура заранее известна):

var user2 = < name: 'admin', getname: function () < return this.name; >>; 

Есть и другой способ создания объекта: с помощью конструктора и ключевого слова new.

var user3 = new Object(); // то же самое, что и <>, но на порядок больше кода user3.name = 'admin'; user3.getName = function ()

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

Но все-таки конструкторы — это системные объекты и некоторые из них тоже стоит использовать, например, конструктор Date(). Тем более, что с помощью литерала мы не сможем создать конструктор Date().

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

Конструктор Object() может принимать параметр и делегировать вызов другому встроенному конструктору, вернув в результате объект другого типа.

var obj = new Object(); console.log( obj.constructor === Object ); // true var obj = new Object(1); // здесь произойдет перевызов и создасться не пустой объект, а объект типа Number со всеми присущими ему методами console.log( obj.constructor === Number ); // true console.log( 'obj.toFixed(3) = ' + obj.toFixed(3) ); // 1.000 var obj = new Object('Hello world'); console.log( obj.constructor === String ); // true var obj = new Object(true); console.log( obj.constructor === Boolean ); // true 

Из примеров выше понятно, в какой тип данных будет преобразован Object по литералу в параметрах вызова. Однако, если мы передаем в параметры переменную, определенную где-то выше в приложении, то уже становится не понятно, в какой тип будет преобразован Object. Такой код нечитабелен и сложнее будет сопровождаться в будщем: var obj = new Object(a); .

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

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

Во-первых, идентификатор (имя) конструктора всегда пишется с заглавной буквы. И это не соглашение между разработчиками, как многие думают. Это заложено в самом языке. Убедиться в этом можно, если вызвать в консоли объект Window и посмотреть на его свойства и методы: сначала будут идти методы с заглавной буквы — это конструкторы, которые нужно вызывать с ключевым словом new; а затем будут идти методы с прописной буквы — это обычные методы, которые выполняют какую-то функцию.

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

При вызове функции с оператором new происходит следующее:

  1. Создается пустой объект
  2. Пустой объект наследует свойства и методы прототипа функции
  3. Ссылка на этот объект сохраняется в переменной this
  4. В конструкторе добавляются новые свойства и методы в пустой объект.
  5. В конце функции неявно возвращается объект, на который ссылается this
function User(name) < this.name = name; // this - контекст this.say = function () < document.write( 'Hello! My name is ' + this.name ); >> var user = new User('John'); 

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

Методы конструктора лучше не писать в нем самом, а выносить за передлы конструктора в прототип.

function User2(name) < this.name = name; // Создавая метод в объекте бессмысленно расходуется память, // т.к. каждый новый объект, созданный этой функцией конструктором, будет содержать в себе копию метода. // this.say = function () < // document.write( 'Hello! My name is ' + this.name ); // >> // Хорошей практикой считается добавление методов к прототипу конструктора User2.prototype.say = function () < document.write( 'Hello! My name is ' + this.name ); >var user = new User2('Иван'); 

По сути, когда мы пишем оператор new для вызова функции, то контекстом этой функции будет новый объект. Без оператора new контекст функции будет ссылаться на глобальный объект.

function User3(name) < this.name = name; >var a = new User3('Стив Джобс'); // вызываем функцию через оператор new console.log( a.name ); // Стив Джобс - контекст функции ссылается на новый объект var b = User3('Билл Гейтс'); // вызываем функцию без оператора new console.log( b ); // undefined console.log( window.name ); // Билл Гейтс - контекст функции ссылается на глобальный объект 

В сухом остатке:

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

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

Шаблон принудительного вызова ключевого слова new №1

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

function User4(name) < var that = <>; that.name = name; return that; this.name = name; > var a = new User4('Альберт Эйнштейн'); console.log( a.name ); // Альберт Эйнштейн var b = User4('Нильс Бор'); console.log( b ); // Object console.log( window.name ); // undefined 

Шаблон принудительного вызова ключевого слова new №2

Сохраняется связь с прототипом

function User5(name) < // Если контекст не является экземпляром конструктора, а стало быть это экземпляр window if ( ! (this instanceof User5) ) < return new User5(name); // то возвращаем вызов конструктора с помощью оператора new >this.name = name; > var a = new User5('Бред Питт'); console.log( a.name ); // Бред Питт var b = User5('Джони Депп'); console.log( b ); // User5 console.log( window.name ); // undefined 

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

В JS нет массивов в том понимании, в котором мы привыкли в других ЯП. Массив в C# — это непрерывная последовательность байт в оперативной памяти. Мы не можем просто так добавить в этот массив новый элемент, не создав новый массив на большее кол-во записей.

В JS массивы — это обычные объекты и нет разницы между объектом, который был создан фигурными скобками <> и объектом, который был создан квадратными скобками [] с точки зрения организации в оперативной памяти. Объект — это набор значений, где у каждого значения есть свое имя. Массив — это набор значений, где у каждого значения есть свой порядковый номер.

Массивы в JS — это аналог ассоциативных массивов в других языках, например, как dictionary в языке C#, где записи представляют собой пары ключ-значение.

Массивы тоже желательно создавать с помощью литерала.

Формально массивы в JS всегда рассматриваются отдельно, но номинально такого типа данных как Array в JS не существует.

var someArrayA = new Array('Hello! ', 'World', '!'); var someArrayB = ['Hello! ', 'World', '!']; document.write( typeof someArrayA ); // object document.write( someArrayA.constructor === Array ); // true document.write( typeof someArrayB ); // object document.write( someArrayB.constructor === Array ); // true 

Неважно как мы создали массив: с помощью конструктора или литерала. В любом случае он будет принадлежать к типу данных object и для создания объекта используется конструктор Array().

Кроме того, при использовании конструктора, есть подводные камни:

var someArrayC = new Array(); // пустой массив var someArrayD = new Array('Hello! ', 'World', '!'); // массив на 3 элемента со значениями 

Если конструктору массива передать 1 значение, то оно НЕ станет первым элементом массива.

var someArrayE = new Array(10); // пустой массив на 10 элементов var someArrayF = new Array(3.5); // ошибка - нельзя создать массив на 3.5 элемента var someArrayD = new Array('Hello!'); // Ошибка - нельзя создать массив на кол-во элементов Hello! 

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

Работа с простыми (примитвными) типами данных

Примитивы также лучше определять с помощью литералов.

var someNumA = 100; // простое число, тип number

var someNumB = new Number(100);

Вторая запись: 1) длиннее; 2) конструктор будет тянуть за собой все свои методы, а оно надо? 3) при проверке на тип, будет возвращать object, а не number

Возникает вопрос: если мы создаем примитивы с помощью литералов, а у них тип не object, то как же тогда пользоваться методами типа toString() или toFixed() и т.п.? Ответ простой: вызывать на примитивах методы точно так же, как если бы мы пользовались объектами. Дело в том, что во время вызова метода на примитиве, он временно преобразуется в объект.

var str = 'hello world'; document.write( str.toUpperCase() ); // при вызове метода строка временно преобразуется в объект String document.write( 'hello'.length ); // Свойства и методы можно вызывать непосредственно на значении 

Поэтому для создания объектов лучше использовать литералы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *