Javascript Object: створення об'єктів та робота. Властивості та методи об'єктів. Створення нового об'єкту

Останнє оновлення: 08.04.2018

Об'єктно-орієнтоване програмування на сьогоднішній день є однією з панівних парадигм у розробці додатків, і JavaScript ми також можемо використовувати всі переваги ООП. У той же час стосовно JavaScript об'єктно-орієнтоване програмування має деякі особливості.

Об'єкти

У минулих темах ми працювали з примітивними даними - числами, рядками, але дані не завжди є примітивними типами. Наприклад, якщо в нашій програмі нам треба описати сутність людини, яка має ім'я, вік, стать і так далі, то природно ми не зможемо уявити сутність людини у вигляді числа або рядка. Нам потрібно кілька рядків чи чисел, щоб належним чином описати людину. У цьому плані людина виступатиме як складна комплексна структура, яка матиме окремі властивості - вік, зростання, ім'я, прізвище тощо.

Для роботи з подібними структурами JavaScript використовуються об'єкти . Кожен об'єкт може зберігати властивості, що описують його стан, та методи, що описують його поведінку.

Створення нового об'єкту

Існує кілька способів створення нового об'єкта.

Перший спосіб полягає у використанні конструктора Object:

Var user = новий Object();

В даному випадку об'єкт називається user. Він визначається так само, як і будь-яка звичайна змінна за допомогою ключового слова var .

Вираз new Object() представляє виклик конструктора - функції, що створює новий об'єкт. Для виклику конструктора використовується оператор new. Виклик конструктора фактично нагадує виклик звичайної функції.

Другий спосіб створення об'єкта представляє використання фігурних дужок:

Var user = ();

На сьогоднішній день найпоширенішим є другий спосіб.

Властивості об'єкту

Після створення об'єкта ми можемо визначити властивості. Щоб визначити властивість, треба після назви об'єкта через точку вказати ім'я властивості та надати йому значення:

Var user = (); user.name = "Tom"; user.age = 26;

У разі оголошуються дві властивості name і age , яким присвоюються відповідні значення. Після цього ми можемо використовувати ці властивості, наприклад вивести їх значення в консолі:

Console.log(user.name); console.log(user.age);

Також можна визначити властивості щодо об'єкта:

Var user = (name: "Tom", age: 26);

У цьому випадку для присвоєння значення властивості використовується символ двокрапки, а після визначення властивості ставиться кома (а не крапка з комою).

Крім того, доступний скорочений спосіб визначення властивостей:

Var name = "Tom"; var age = 34; var user = (name, age); console.log(user.name); // Tom console.log(user.age); // 34

У разі назви змінних також є і назвами властивостей об'єкта. І таким чином можна створювати складніші конструкції:

Var name = "Tom"; var age = 34; var user = (name, age); var teacher = (user, course: "JavaScript"); console.log(teacher.user); // (name: "Tom", age: 34) console.log(teacher.course); // JavaScript

Методи об'єкту

Методи об'єкта визначають його поведінку чи дії, що він виробляє. Методи є функції. Наприклад, визначимо метод, який би виводив ім'я та вік людини:

Var user = (); user.name = "Tom"; user.age = 26; user.display = function()( console.log(user.name); console.log(user.age); ); // виклик методу user.display();

Як і у випадку з функціями, методи спочатку визначаються, а потім уже викликаються.

Також методи можуть визначатися безпосередньо щодо об'єкта:

Var user = ( name: "Tom", age: 26, display: function()( console.log(this.name); console.log(this.age); ) );

Як і у випадку з властивостями, методу присвоюється посилання на функцію за допомогою двокрапкового знака.

Щоб звернутися до властивостей або методів об'єкта всередині цього об'єкта, використовується ключове слово this . Це означає посилання на поточний об'єкт.

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

Var user = ( name: "Tom", age: 26, display()( console.log(this.name, this.age); ), move(place)( console.log(this.name, "goes to") , place);))); user.display(); // Tom 26 user.move ("the shop"); // Tom goes to the shop

Синтаксис масивів

Існує також альтернативний спосіб визначення властивостей та методів за допомогою синтаксису масивів:

Var user = (); user["name"] = "Tom"; user["age"] = 26; user["display"] = function()( console.log(user.name); console.log(user.age); ); // виклик методу user["display"]();

Назва кожної властивості або методу полягає в лапки і квадратні дужки, потім їм також присвоюється значення. Наприклад, user["age"] = 26 .

При зверненні до цих властивостей і методів можна використовувати нотацію точки (user.name), або звертатися так: user["name"]

Рядки як властивості та методи

Також слід зазначити, що назви властивостей та методів об'єкта завжди є рядками. Тобто ми могли попереднє визначення об'єкта переписати так:

Var user = ( "name": "Tom", "age": 26, "display": function()( console.log(user.name); console.log(user.age); ) ); // виклик методу user.display();

З одного боку, різниці немає між двома визначеннями. З іншого боку, трапляються випадки, де висновок назви в рядок можуть допомогти. Наприклад, якщо назва властивості складається з двох слів, розділених пробілом:

Var user = ( name: "Tom", age: 26, "full name": "Tom Johns", "display info": function()( console.log(user.name); console.log(user.age) ;))); console.log(user["full name"]); user["display info"]();

Тільки в цьому випадку для звернення до подібних властивостей та методів ми маємо використовувати синтаксис масивів.

Видалення властивостей

Вище ми подивилися, як динамічно додавати нові властивості до об'єкта. Однак також ми можемо видаляти властивості та методи за допомогою оператора delete. І як і у разі додавання ми можемо видаляти властивості двома способами. Співаний спосіб - використання нотації точки:

Delete об'єкт.

Або використовувати синтаксис масивів:

Delete об'єкт["властивість"]

Наприклад, видалимо властивість:

Var user = (); user.name = "Tom"; user.age = 26; user.display = function()( console.log(user.name); console.log(user.age); ); console.log(user.name); // Tom delete user.name; // видаляємо властивість // альтернативний варіант // delete user ["name"]; console.log(user.name); // undefined

Після видалення властивість буде не визначено, тому при спробі звернення до нього програма поверне значення undefined.

Вітаю всіх, хто читає цю публікацію. Сьогодні я хочу розібрати з вами ключовий інструмент мови – JavaScript. Нагадаю, що js є кросбраузерним і функціонує у всіх ОС (windows, mac os тощо). На відміну від об'єктно-орієнтованих мов програмування, js реалізація об'єктів значно відрізняється від звичного функціоналу і варіацій використання екземплярів, наприклад, C#.

Тому після прочитання поточної статті ви пізнаєте основні особливості скриптових об'єктів, дізнаєтеся, якими способами їх можна створити, оновити і видалити. Також я торкнуся теми, що стосується властивостей, методів і конструкторів, розповім про корисних командахі звичайно ж трохи про успадкування. Думаю, настав час приступати до навчання!

Що являє собою об'єкт у JavaScript і які можливості має?

У js об'єктами є прості асоціативні масиви (їх також називають хешами).

Що таке асоціативний масив?

Це структура даних, у якій зберігається певну кількість інформації, що стосується і описує певний елемент. Усі дані структуровані і пов'язані між собою як «ключ = значення».

Наприклад, потрібно описати автомобілі. Тоді ви створюєте об'єкт avto і описуєте в масиві його параметри. Я вирішив описати марку машини (name), її колір (color) та вартість (price). Нижче я прикріпив код реалізації описаного завдання.

1 2 3 4 5 var avto = (назва: "BMW 116i", колір: "black", cena: 588000);

var avto = (назва: "BMW 116i", колір: "black", cena: 588000);

Ось ви бачите один із способів створення об'єкта з ім'ям avto. Name, color і price є ключами, за якими можна буде звертатися під час написання програми.

Цим прикладом я забіг уперед, тож зараз розберемо все по порядку.

Створити об'єкт можна кількома способами:

var avto = (); чи var avto = new Object();

В обох випадках створюється порожній об'єкт з відомим ім'ямАле першим варіантом користуються набагато частіше, тому що його коротше і зручніше писати.

Все про властивості

Тепер потрібно заповнити порожній об'єкт параметрами. Для цього необхідно додати властивості, які також вище називав я ключами. І знову ж таки існує два способи оголошення властивостей.

Хочу зазначити, що JavaScript не має строгих рамок щодо створення та ініціалізації таких параметрів. Нові властивості можуть з'являтися протягом усього коду, так само як видалятися та оновлюватися.

Таким чином, можна відразу створити всі ключі або оголошувати їх у міру надходження. І навіть якщо під час написання програми ви звернетеся до неіснуючих ключів, помилки не буде. І тут повернеться “undefined”.

Перший метод.

Створення та звернення до властивостей через точку. Для реалізації такого випадку необхідно написати ім'я об'єкта, а потім через точку приписати до нього найменування ключа і далі через символ і привласнити якесь значення:

avto.name = "BMW 116i"

А ось у такий спосіб до існуючих ключів ви додасте ще один елемент:

Цей спосіб використовується тоді, коли ім'я властивості вже відоме і потрібно виконати певні дії зі значеннями.

Другий спосіб.

Нічим не відрізняється від першого, якщо порівнювати їх призначення. Однак цей спосіб має невелику перевагу. Для такого варіанта використовуються квадратні дужки:

avto[“name”] = “BMW 116i”

А приємним додаванням є можливість створювати назву властивостей у вигляді будь-якого рядка. Наприклад,

avto[“name of the car”] = “BMW 116i”

Робота з ключами через квадратні дужки використовується тоді, коли якісь параметри вводяться користувачем і зберігаються в змінних або коли наперед невідомі назви властивостей. Наприклад, користувач запитує вартість вибраного автомобіля. У змінну записується елемент, який був викликаний, а у відповідь передається ціна:

var avto = (); avto.name = "BMW_116i"; avto.price = 588000; var key = "price"; // було запрошено вартість машини alert(avto);

Тепер перейдемо до видалення властивостей. Тут усе дуже просто. Для видалення використовується команда delete. Так, якщо до останнього прикладу знизу дописати такі 2 рядки:

delete avto.price;

alert (avto);

То із викликом alert вдруге діалогове вікно видасть “undefined”.

Декілька слів про компактність

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

А все тому, що там використовується компактне представлення даних. Це дуже популярний метод оголошення ключів, тому що він коротший при написанні та легше сприймається візуально.

Давайте переберемо наші властивості

JavaScript можна швидко перебрати створені властивості. Для цього було передбачено спеціальний механізм, більш відомий як цикл.

Якщо ви знайомі з іншими мовами програмування, то знаєте, що найчастіше цикли створюються за допомогою слова for, Далі в круглих дужках прописується умова перебору елементів.

У js воно нагадує своїм зовнішнім виглядомцикл foreachз мови C#. Ознайомтеся із загальним виглядом конструкції:

for (var obj in object) ( // Виконання перебору)

де obj відповідає за назву перерахованих ключів,

object - за їх значення.

А тепер ось вам конкретний приклад.

1 2 3 4 5 6 7 8 var avto = (назва: "BMW 116i", колір: "black", cena: 588000); for (var obj in object) ( alert(obj + ":" + object) )

var avto = (назва: "BMW 116i", колір: "black", cena: 588000); for (var obj in object) ( alert(obj + ":" + object) )

Настав час познайомитися з методами

У скриптовій мові передбачено створення методів. Це абсолютно простий механізм, за допомогою якого будь-коли до будь-якого об'єкта можна дописати метод або методи, які розширюють можливості створених асоціативних масивів. Їх також називають властивостями-функціями.

Js сам по собі дуже динамічний і дивовижний певною мірою. Це полягає в тому, як можна створювати елементи різних типів. При вивченні цієї мови не потрібно запам'ятовувати складних конструкцій, оскільки багато оголошень дуже схожі між собою.

Так, для створення методу, потрібно оголосити об'єкт, а потім почати писати команду, яка точнісінько нагадує створення властивостей. Проте після «=» пишеться не значення, а ключове слово function (змінна). А далі у фігурних дужках ведеться перелік дій.

Ось реалізація цього механізму:

var avto =() avto.name = "BMV" avto.year = 1999 avto.drive = function(k) ( alert(«Автомобіль проїхав»+n+«км. »)) avto.drive(300) avto.drive( 450)

Як бачите, цей приклад містить властивості та методи, виклик яких спочатку ідентичний.

У JS є ще конструктори?

Так точно! У цій мові все, що використовує ключове слово. new», автоматично стає конструктором. Так, вище ви бачили оголошення порожнього об'єкта як: avto = new Object ();. Це і є конструктор.

Для наочності розгляньте нижченаведені рядки.

var bob = new Object();

bob.name = "Bob Smith";

Однак, це не весь арсенал можливостей. У js можна створювати власні конструктори і після використовувати їх для оголошення нових об'єктів.

Отже, я хочу «змайструвати» конструктор для вже рідних автомобілів. Зауважте, що ім'я треба писати з великої літери. Це риса функцій. Для цього я пишу ось таку програмну реалізацію:

функція Avto (name, price) (

this.name = name;

this.price = price;

Тепер при створенні необмеженої кількості об'єктів та застосування до них цього конструктора всі вони будуть ставитись до одного класу. Наприклад:

var car1 = новий Авто («BMW», 650000);

var car2 = новий Авто («Audi», 520000);

На додаток до цього всередині конструктора можна створювати методи.

Особливості успадкування JavaScript

Зазвичай у багатьох мовах успадкування ґрунтується на класах, які можуть успадковувати один одного. Тоді можна почути такі вирази, як клас-предок, дочірній клас і т.д.

Однак у js все інакше. Тут успадковуються об'єкти.

Все успадкування ґрунтується на внутрішньому засланніміж об'єктами, яка відома під назвою «прототип». Якщо до методу приписати через точку «.prototype», а далі прописати ім'я прототипу, всі об'єкти обраного методу будуть успадковуватися від цього прототипу.

Перейдемо, наприклад.

function Transport (name) ( this.name = name this.canDrive = true ) var transport = new Transport ( "avto") // створили об'єкт transport function Bike (name) ( this.name = name ) Bike.prototype = transport / / вказуємо, що всі нові об'єкти цього класу будуть використовувати як прототип transport bike1 = new Bike ("for_sport") bike2 = new Bike ("for_child") console.log(bike1.name) console.log(bike2.name) console .log(bike1.canDrive)

На цьому я, мабуть, закінчу. Я розповів вам про фундаментальні аспекти скриптової мови. Однак це лише поверхневі знання. Далі будемо заглиблюватись. А поки не забувайте вступати до лав моїх передплатників та ділитися посиланням на статтю з друзями. Успіхів!

Бувай!

З повагою, Роман Чуєшов

Прочитано: 97 разів

Об'єкти є наріжним каменем JavaScript. Багато вбудованих типів даних представлені як об'єкти. Щоб бути успішним розробником JavaScript потрібно мати чітке уявлення, як вони працюють. Будівельні блоки об'єкта називають його полями або властивостями об'єкта JavaScript. Вони використовуються для опису будь-якого аспекту об'єкта. Властивість може описувати довжину списку, колір піднебіння або дату народження людини. Створення об'єктів є легким процесом. Мова надає синтаксис, відомий як об'єктні літерали, що позначаються фігурними дужками.

Доступ до властивостей

Мова надає два записи для доступу до властивостей. Перший і найпоширеніший відомий як точкове позначення. При точковій нотації доступ до ресурсу можна отримати, вказавши ім'я об'єкта хоста, за яким слідує період та ім'я властивості. Наприклад, коли object.foo спочатку було надано значення one, тоді його значення стане 2 після виконання оператора JavaScript об'єктів.

Альтернативний синтаксис для доступу відомий як запис у вигляді дужок. У нотації за ім'ям об'єкта слідує набір квадратних дужок. Вони ім'я властивості вказується як рядок:

object["foo"] = object["foo"] + 1.

Вона виразніша, ніж точкова нотація, оскільки дозволяє змінної вказувати все чи частину імені властивості. Це можливо, тому що інтерпретатор JavaScript об'єктів автоматично перетворює цей вираз на рядок і потім отримує відповідну властивість. Імена властивостей створюються «на льоту» шляхом конкатенації вмісту змінної f з рядком "oo":

object = "bar".

Позначення дужок дозволяє іменам властивостей містити символи, заборонені в точковій нотації. Наприклад, наступний оператор повністю легальний у дужках. Однак якщо користувач спробує створити те саме ім'я властивості в точковій нотації, він зіткнеться з синтаксичною помилкою:

object["!@#$% &*()."] = true.

Доступ до властивостей вкладених JavaScript об'єктів можна отримати шляхом зв'язування точок та/або дужок. Наприклад, наступний об'єкт містить вкладений об'єкт з ім'ям baz, що містить інший об'єкт з ім'ям foo, який має властивість з ім'ям bar, що містить п'ять:

var object = (baz: (foo: (bar: 5)))).

Наступні вирази одержують доступ до вкладеної властивості bar. У першому виразі використовується точкова нотація, тоді як друге вираз використовує квадратну нотацію. Третій вираз об'єднує обидва записи для досягнення одного й того самого результату:

  • object.baz.foo.bar;
  • object["baz"]["foo"]["bar"];
  • object["baz"].foo["bar"].

Вирази, подібні до показаних у попередньому прикладі, можуть призвести до погіршення продуктивності при неправильне використаннята вивести об'єкт JavaScript з ладу. Оцінка кожного виразу точки чи дужки вимагає часу. Якщо одна й та сама властивість використовується кілька разів, тоді є сенс отримати доступ до властивості один раз, а потім зберегти значення в локальній змінній для всіх майбутніх цілей.

Функція як метод

Коли функція використовується як властивість об'єкта вона називається методом. Подібно до властивостей, вони вказані в нотації об'єктних літералів. Наприклад:

var object = (sum: function (foo, bar) (return foo + bar;)).

Методи JavaScript-об'єкта можуть викликатися з використанням міток та дужок. Наступний приклад викликає sum() метод із попереднього прикладу, використовуючи обидва записи:

  • object.sum(1, 2);
  • object["sum"](1, 2).

Позначення літералу об'єкта є корисним для створення нових об'єктів, але воно не може додавати властивості або методи до існуючих. На щастя, додавання нових даних так само просто, як створення оператора присвоєння. Створюється пустий об'єкт. Потім за допомогою операторів присвоювання додаються дві властивості, foo, а bar, а також метод baz:

  • var object = ();
  • object.foo = 1;
  • object.bar = null;
  • object.baz = function() ( return "hello from baz()"; ).

Інкапсуляція програм

Основна ідея об'єктно-орієнтованого програмування полягає в тому, щоб розділити програми на дрібніші частини та зробити кожну з них відповідальною за керування своїм власним станом. Таким чином, деякі знання, як працює частина програми, можуть бути локальними для цієї частини. Хтось, хто працює над рештою програми, не повинен пам'ятати або навіть знати про це. Щоразу, коли ці локальні дані змінюються, необхідно оновлювати лише код безпосередньо навколо нього.

Різні частини такої програми взаємодіють один з одним через інтерфейси, обмежені набори функцій або прив'язок, які забезпечують корисну функціональність більш абстрактному рівні, приховуючи їх точну реалізацію. Такі частини програми моделюються з використанням об'єктів. Їхній інтерфейс складається з певного набору методів та властивостей. Властивості, які є частиною інтерфейсу, називають загальнодоступними. Інші, які повинні стосуватися зовнішнього коду, називаються приватними.

Багато мов надають можливість розрізняти публічні та приватні властивості і не дозволяють зовнішньому коду отримати доступ до приватних. JavaScript, який знову-таки взяв мінімалістський підхід, ще не досягнуто. В даний час ведеться робота з додавання цієї мови. Тому JavaScript-програмісти успішно використовуватимуть цю ідею. Як правило, доступний інтерфейсописаний у документації чи коментарях. Також прийнято поміщати символ підкреслення (_) на початку імен властивостей, щоб вказати, що ці властивості є приватними. Поділ інтерфейсу від реалізації - чудова ідея. Її зазвичай називають інкапсуляцією.

Властивості

Об'єкт із дужками (...) називається літералом об'єкта. Можна відразу помістити деякі властивості у такі дужки (...). Наприклад, пари «ключ: значення тощо»:

let user = ( // an object name: "John", // by key "name" store value "John" age: 30 // by key "age" store value 30 }.!}

Властивість має ключ (також відомий як «ім'я» або «ідентифікатор») перед двокрапкою ":" та значення праворуч від нього. У user-об'єкті є дві властивості. Результуючий user JavaScript об'єкт із двома підписаними файлами з написом «ім'я» та «вік». Можна додавати, видаляти та читати файли з нього у будь-який час. Значення властивостей доступні за допомогою точкової нотації. Воно може бути будь-якого типу. Можна додати логічне значення. Щоб видалити властивість, використовують delete у разі Error об'єкта JavaScript.

Усі об'єкти помилки JavaScript є нащадками Error об'єкта або успадкованим об'єктом:

  1. Syntax Error об'єкт успадковується від Error об'єкта.
  2. JSON Parse є помилка певного типу Syntax Error об'єкта.

Щоб ще глибше поринути в розуміння того, як програми мають справу з помилками JavaScript, краще ознайомиться з Airbrake JavaScript - інструментом відстеження помилок для сповіщень в реальному часі та миттєвим розумінням того, що пішло не так з кодом JavaScript.

Повідомлення про помилки, які може отримати користувач перед тим, як видалити JavaScript об'єкт:

  1. Поганий символ управління у рядковому літералі.
  2. Поганий символ у рядковому літералі.
  3. Поганий вихід Unicode.
  4. Поганий escape символ.
  5. Unterminated string.
  6. Несподіваний цифровий код.
  7. Відсутні цифри після десяткової точки.
  8. Unterminated дрібне число.
  9. Відсутні цифри після індикатора ступеня.
  10. Відсутні цифри після символу експонента.
  11. Експонентна частина не має числа.
  12. Несподіваний кінець даних.
  13. Несподіване ключове слово.
  14. Несподіваний символ.
  15. Кінець даних під час читання вмісту об'єкта.
  16. Очікуване ім'я властивості або ")".

Обчислювальні властивості

Можна використовувати квадратні дужки у об'єктному літералі. Це називається обчисленими властивостями. Приклад наведено нижче.

Значення обчислюваного властивості просте: означає, що ім'я властивості має бути взято з fruit. Отже, якщо відвідувач входить "apple", bag стане (apple: 5). Можна використовувати більше складні виразиу квадратних дужках:

let fruit = "apple";

: 5 // bag.appleComputers = 5

Квадратні дужки набагато потужніші, ніж точкові позначення. Вони допускають імена та змінні властивостей. Але вони також більш громіздкі для написання. Тому більшість часу, коли імена властивостей відомі і прості, використовується крапка. І якщо потрібно щось складніше, то перемикаються на квадратні дужки.

Резервування слів

Змінна не може мати ім'я, що дорівнює одному із зарезервованих слів, таких як «за», «нехай», «повертати» тощо. Але при сортуванні об'єктів JavaScript немає такого обмеження.


В принципі, будь-яке ім'я дозволене, але є спеціальним: воно "__proto__" отримує спеціальне звернення з історичних причин. Наприклад, не можна встановити його для значення, відмінного від об'єкта:

obj.__proto__ = 5;

alert(obj.__proto__); // , didn"t work as intended

Як очевидно з коду, призначення примітиву 5 ігнорується. Це може стати джерелом помилок і навіть уразливостей, якщо оператор має намір зберігати довільні пари ключ-значення в об'єкті та дозволяти відвідувачу вказувати ключі. У цьому випадку відвідувач може вибрати «proto» як ключ і додати до об'єкта JavaScript. Існує спосіб зробити об'єкти обробленими __proto__ як регулярною властивістю. Існує також інша карта структури даних, яка підтримує довільні ключі.

Цілочисленні властивості

Термін «цілочисленна властивість» тут означає рядок, який може бути перетворений з цілого без зміни. Отже, наприклад, «49» - це ціле ім'я властивості, тому що коли воно перетворюється на ціле число і назад, воно все те ж саме. Але «+49» та «1.2» не є такими. З іншого боку, якщо ключі не цілі, то вони перераховуються в порядку створення. Приклад нижче.


Щоб усунути проблему за допомогою телефонних кодів, можна «обдурити», зробивши коди нецілими. Додавання "+" (знака плюс) перед кожним кодом достатньо. Тепер він працюватиме за призначенням.

Відмінність об'єктів від примітивів полягає в тому, що вони зберігаються і копіюються за посиланням. Примітивні значення присвоюються та копіюються «як ціле значення». Змінна зберігає адресу в пам'яті, а не сам об'єкт або посилання на нього. Можна використовувати будь-яку змінну для доступу та зміни вмісту.


У наведеному вище прикладі показано, що існує лише один об'єкт та admin, щоб увійти до нього. Потім, якщо пізніше використовувати інший ключ (user), користувач виявить зміни.

Оператори рівності == та суворої рівності === для об'єктів працюють однаково. Два об'єкти рівні, тільки якщо вони є одним і тим самим об'єктом. Для порівнянь, подібних obj1 > obj2 або для порівняння з примітивом obj == 5, об'єкти перетворюються на примітиви. Чесно кажучи, такі порівняння потрібні дуже рідко і зазвичай є результатом помилки кодування.

Перевірка об'єкта JavaScript

Об'єкти мають доступ до будь-якої якості. Проте, якщо вона взагалі не існує, це не буде помилкою. Тільки доступ до неіснуючої властивості повертає undefined. Він надає дуже поширений спосіб перевірити властивість та порівняти з невизначеним. Нижче наведено приклад.


Використання «in» для властивостей, які зберігаються undefined. Зазвичай строга "=== undefined" перевірка порівняння працює нормально. Є особливий випадок, коли він зазнає невдачі, а "in" працює правильно. Це коли властивість об'єкта існує, але зберігає невизначений.


У наведеному вище коді властивість obj.test технічно існує. Тому оператор працює правильно. Подібні ситуації трапляються дуже рідко, тому що невизначені зазвичай не призначаються. В основному використовуються null "невідомі" або "порожні" значення. Таким чином, оператор, фактично, є гостем у коді.

Цикл "for..in"

Для переміщення по всіх ключах від об'єкта до об'єкта існує спеціальна форма циклу: for..in. Це зовсім інша річ з for(;;) конструкції.

Нижче наведено приклад.


Потрібно звернути увагу, що всі конструктори for дозволяють оголошувати змінну looping всередині циклу як let key. Крім того, натомість можна використовувати інше ім'я змінної key.

Наприклад, for(let prop in obj) також широко використовується.

Існує альтернативна «квадратна дужка», яка працює з будь-яким рядком.


При цьому точка вимагає, щоб ключі JavaScript-об'єкта був допустимим ідентифікатором змінної, тобто немає пропусків та інших обмежень. Потрібно звертати увагу, щоб рядок усередині дужок був правильно процитований. Квадратні дужки також надають спосіб отримати ім'я властивості в результаті будь-якого виразу, на відміну від літерального рядка - зі змінної:

let key = "likes birds";

// same as user["likes birds"] = true;

user = true.

Тут змінна key може бути розрахована під час виконання і залежить від введення користувача, а потім буде використана для доступу до властивості. Це дає програмістам більшу гнучкість. Точкова нотація не може використовуватися аналогічно, оскільки буде перебір об'єкта JavaScript. Нижче наведено приклад.


Об'єкт Const

Оголошений об'єкт const може бути змінено. Приклад наведено нижче.


Може здатися, що об'єкт JavaScript у рядку (*) викликає помилку, але це не так. Це тому, що const фіксує значення самого користувача. І тут user зберігає посилання на той самий об'єкт весь час. Лінія (*) йде всередині об'єкта, вона не призначається user. Const дасть помилку, якщо спробувати встановити user і ще щось. Клонування та злиття, Object.assign створює ще одне посилання на той самий об'єкт, якщо потрібно його дублювати. Це також можна здійснити, але трохи складніше, тому що в JavaScript немає вбудованого методу. Насправді, це необхідно рідко. Копіювання за посиланням застосовується здебільшого. Але якщо це дійсно потрібно, тоді необхідно створити JavaScript-об'єкт і реплікувати структуру існуючого, копіюючи його властивості на примітивному рівні. Нижче наведено приклад.


Також можна використовувати для цього метод Object.assign. Аргументи dest та src1, ..., srcN є об'єктами. Він копіює властивості всіх об'єктів src1, ..., srcNINTO dest. Іншими словами, характеристики всіх аргументів, починаючи з другого, копіюються в 1-й. Потім він повертається dest. Наприклад, можна використовувати його для об'єднання кількох об'єктів на один.


Також можна використовувати Object.assign для заміни циклу простого клонування. Він копіює всі властивості user в порожній об'єкт і повертає його, як і цикл, але коротше. До цього часу передбачалося, що це властивості user примітивні. Але характеристики можуть бути посиланнями на інші об'єкти.

Щоб виправити це, потрібно використовувати цикл клонування, який перевіряє кожне значення user і якщо це об'єкт, потім реплікує його структуру. Це називається "глибоким клонуванням".

Існує стандартний алгоритмглибокого клонування, який обробляє вищенаведений випадок і складніші випадки, звані алгоритмом клонування Structured. Щоб не винаходити колесо, можна використовувати робочу реалізацію з бібліотеки JavaScript, метод називається _.cloneDeep (obj).

Просунуті методи

Якщо програміст зациклюється над об'єктом і прагне отримати всі властивості у тому порядку, в якому вони були додані, він може покладатися на «впорядкування по-особливому», коли цілочисленні властивості сортуються, а інші формуються в порядку створення JavaScript-об'єкта.

Просунуті методи об'єкта мають справу з концепціями, які рідко використовуються JavaScripting. Це з тим, що у звичайних сценаріях ці потужні функції не потрібні. Деякі з цих методів можуть не працювати у старих браузерах, як-от ранні випуски Netscape 4.

Використання прототипу могло бути застосоване для створення JavaScript-об'єктів та всіх методів mycircle, а не лише нових. Це дає змішане навантаження на продуктивність. Вони не повинні зберігати окремі копії методів для кожного екземпляра об'єкта, тому для роботи може знадобитися менше пам'яті, але для їх пошуку браузер повинен шукати поточні та батьківські області. Це може призвести до граничної затримки. Як правило, користувач повинен використовувати те, що підходить для коду, а не засновувати це рішення на продуктивності, якщо він не має справу з дуже певним контрольованим середовищем.


Повернення true

У деяких випадках може бути необхідно, щоб властивість об'єкта була прив'язана до самого об'єкта або в ланцюжку прототипу. У JavaScript всі об'єкти використовують метод hasOwnProperty, який повертає true, якщо ця властивість прив'язана до екземпляра окремого об'єкта. У такому випадку з'являється можливість перевірити, чи має конструктор об'єкта одну і ту ж властивість з тим самим значенням, що і сам екземпляр об'єкта. Це може дати неправильний результат, якщо існують окремі властивості JavaScript однаковим значеннямяк екземпляра об'єкта, так прототипу ланцюга. Метод hawOnProperty приймає єдиний параметр - ім'я властивості у вигляді рядка.


Аналогічно можна створювати приватні методи. Це просто функція, яка створюється усередині функції конструктора. Комусь це може здатися заплутаним, але саме так усе працює. Приватна функція може бути викликана лише самим конструктором чи методами, що визначені у рядку. Вони можуть використовуватися як загальнодоступні методи, якщо призначені публічному конструктору та доступні з використанням відкритих методів Javascript.

function myob() ( function cantBeSeen() ( alert(secretValue);

) var secretValue = "";

this.method1 = function () ( secretValue = "no surprises";!}

this.method2 = cantBeSeen;

) var oneOb = new myob();

oneOb.method1();

/ / alerts "no surprises" oneOb.method2 ();

//Alerts "no surprises".

Шаблон Command

Об'єкти Command допускають слабко пов'язані системи, поділяючи ті, які видають запит від об'єктів і фактично обробляють запит. Ці запити називаються подіями, а код, який обробляє запити, називається обробниками подій.

Припустимо, створюються програми, що підтримують дії буфера обміну Cut, Copy та Paste. Ці дії можуть запускатися по-різному в усьому додатку: системою меню, контекстним меню, наприклад, клацанням правою кнопкоюмиші по текстовому полюабо поєднанням клавіш. Об'єкти Command дозволяють централізувати обробку цих дій по одній для кожної операції, коли потрібна лише одна команда для обробки всіх запитів Cut, одна для всіх запитів на копіювання та одна для всіх запитів Paste.

Оскільки команди централізують всю обробку, вони також часто беруть участь у обробці функцій скасування для всієї програми. Значних поліпшень можуть бути досягнуті шляхом застосування сучасних методів JavaScript, що призводять до створення більш ефективних, надійних та підтримуваних програм.

Для того, щоб дізнатися, як це зробити, можна використовувати шаблони JavaScript + jQuery. Цей унікальний пакет включає оптимізований JavaScript для всіх шаблонів GoF з використанням більш сучасних функцій, таких як простори імен, прототипи, модулі, функціональні об'єкти, закриття, анонімні функції та інше. Якщо користувачам потрібні новітні інструменти та методи для шаблонів JavaScript, шаблонів jQuery та архітектур шаблонів, тоді це найкращий варіант використання. Цей пакет містить цінну, актуальну інформаціюдля розробників JavaScript. Ось що до нього включено:

  1. JavaScript-оптимізовані шаблони GoF.
  2. Сучасні шаблони дизайну JavaScript.
  3. Шаблони проектування Model-View.
  4. jQuery дизайн шаблонів.
  5. Архітектурні шаблони JavaScript-ідіоми.
  6. Приклади додатків (MVC, SPA тощо)

Запропоновані основи синтаксису об'єктів JavaScript дуже важливі для програмістів-початківців. Потрібно спочатку зрозуміти об'єкти, тоді знання об'єктно-орієнтованого програмування. Дуже важливо мати глибоке розуміння цього матеріалу, оскільки це є основою для решти мови JavaScript.

Об'єкти

Об'єкт є фундаментальним типом даних у JavaScript. Об'єкт- це складове значення: він об'єднує в собі набір значень (простих значень чи інших об'єктів) і дозволяє зберігати та отримувати ці значення за іменами.

Об'єкт є невпорядкованою колекцією властивостей, кожна з яких має ім'я та значення. Імена властивостей є рядками, тому можна сказати, що об'єкти відображають рядки значення. Таке відображення рядків значення може називатися по-різному: можливо, ви вже знайомі з такою фундаментальною структурою даних, як «хеш», «словник» або «асоціативний масив». Однак об'єкт є чимось більшим, ніж просте відображення рядків у значення.

Крім власних властивостей об'єкти в JavaScript можуть також успадковувати властивості від інших об'єктів, відомих під назвою «прототипи». Методи об'єкта – це типові представники успадкованих властивостей, а « успадкування через прототипи» є ключовою особливістю JavaScript.

Об'єкти в мові JavaScript є динамічними – зазвичай вони дозволяють додавати та видаляти властивості – але вони можуть використовуватися також для імітації статичних об'єктів та «структур», які є в мовах програмування зі статичною системою типів. Крім того, вони можуть використовуватися (якщо не враховувати, що об'єкти відображають рядки у значення) для представлення множини рядків.

Будь-яке значення в мові JavaScript, яке не є рядком, числом, true, false, null або undefined, є об'єктом. І навіть рядки, числа та логічні значення, що не є об'єктами, можуть поводитися як незмінні об'єкти (мають об'єкти-обгортки String, Number тощо).

Об'єкти є значеннями, що змінюються, і операції з ними виконуються за посиланням, а не за значенням. Якщо змінна x посилається об'єкт, і виконується інструкція var y = x; у змінну y буде записано посилання на той самий об'єкт, а не його копію. Будь-які зміни, що виконуються в об'єкті за допомогою змінної y, також відображатимуться на змінній x.

Властивість має ім'я та значення. Ім'ям властивості може бути будь-який рядок, включаючи і порожній рядок, але об'єкт не може мати дві властивості з однаковими іменами. Значення властивості може бути будь-яке значення, допустиме в мові JavaScript, або (ECMAScript 5) функція читання або запису (або обидві).

На додаток до імен і значень, кожна властивість має ряд асоційованих з ним значень, які називають атрибутами властивості :

    Атрибут writableвизначає доступність значення якості запису.

    Атрибут enumerableвизначає доступність імені властивості для перерахування циклі for/in.

    Атрибут configurableвизначає можливість налаштування, тобто. видалення властивості та зміни його атрибутів.

До появи стандарту ECMAScript 5 усі властивості в об'єктах, створювані програмою, доступні для запису, перерахування та налаштування. ECMAScript 5 передбачає можливість налаштування атрибутів ваших властивостей.

На додаток до властивостей кожен об'єкт має три атрибута об'єкта :

    Атрибут classмістить рядок з ім'ям класу об'єкта та визначає тип об'єкта.

    Прапор extensible(ECMAScript 5) вказує на можливість додавання нових властивостей до об'єкта.

Нарешті, наведено нижче опис деяких термінів, які допоможуть нам розрізняти три великі категорії об'єктів у мові JavaScript і два типи властивостей:

Об'єкт базової мови

Це об'єкт чи клас об'єктів, який визначається специфікацією ECMAScript. Масиви, функції, дати та регулярні вирази (наприклад) є об'єктами базової мови.

Об'єкт середовища виконання

Це об'єкт, який визначається середовищем виконання (таким як веб-браузер), куди вбудований інтерпретатор JavaScript. Об'єкти HTMLElement, що представляють структуру веб-сторінки в JavaScript, є об'єктами середовища виконання. Об'єкти середовища виконання можуть бути об'єктами базової мови, наприклад, коли середовище виконання визначає методи, які є звичайними об'єктами Function базової мови JavaScript.

Об'єкт користувача

Будь-який об'єкт, створений у результаті виконання програмного коду JavaScript.

Власна властивість

Це властивість, що визначається у даному об'єкті.

Успадкована властивість

Це властивість, що визначається прототипом об'єкта.

Створення об'єктів

Об'єкти можна створювати за допомогою літералів об'єктів, ключового слова new та (в ECMAScript 5) функції Object.create().

Літерали об'єктів

Найпростіший спосіб створити об'єкт полягає у включенні до програми літералу об'єкта. Літерал об'єкта - це ув'язнений фігурні дужкисписок властивостей (пар ім'я/значення), розділених комами. Ім'ям властивості може бути ідентифікатор або рядковий літерал (допускається використовувати пустий рядок). Значенням властивості може бути будь-який вираз, допустимий JavaScript - значення виразу (це може бути просте значення або об'єкт) стане значенням властивості.

Нижче наведено кілька прикладів створення об'єктів:

Var empty = (); // Об'єкт без властивостей var point = (x: 0, y: 0); // Дві властивості var point2 = (x: point.x, y: point.y + 1); // Більш складні значення var site = ( "url site": "www..NET Framework", // і дефісами, тому ісп. лапки author: ( // Значенням цієї властивості є firstname: "Alexandr", // об'єкт). Зверніть увагу, що surname: "Frolov" // імена цих властивостей без лапок.)));

У ECMAScript 5 (і в деяких реалізаціях ECMAScript 3) допускається використовувати зарезервовані слова як імена властивостей без лапок. Проте в цілому імена властивостей, що збігаються з зарезервованими словами, в ECMA-Script 3 повинні полягати в лапки. У ECMAScript 5 остання кома, яка слідує за останнім властивістю в літералі об'єкта, ігнорується. У більшості реалізацій ECMAScript 3 коми також ігноруються, але IE інтерпретує їх наявність як помилку.

Літерал об'єкта - це вираз, який створює та ініціалізує новий об'єкт щоразу, коли проводиться обчислення цього виразу. Значення кожної властивості обчислюється наново, коли обчислюється значення літералу. Це означає, що за допомогою єдиного літералу об'єкта можна створити безліч нових об'єктів, якщо цей літерал помістити в тіло циклу або функції, яка буде викликатися багаторазово, і значення властивостей цих об'єктів можуть відрізнятися один від одного.

Створення об'єктів за допомогою оператора new

Оператор new створює та ініціалізує новий об'єкт. За цим оператором має йти ім'я функції. Функція, використовувана в такий спосіб, називається конструктором і служить ініціалізації новоствореного об'єкта. Базовий JavaScript включає множину вбудованих конструкторів для створення об'єктів базової мови. Наприклад:

Var o = New Object(); // Створити новий порожній об'єкт: те, що і () var a = new Array(); // Створити порожній масив: те, як і var d = new Date(); // Створити об'єкт Date, що становить поточний час var r = new RegExp("js"); // Створити об'єкт RegExp для операцій зіставлення із шаблоном

Крім цих вбудованих конструкторів є можливість визначати свої власні функції-конструктори для ініціалізації новостворених об'єктів. Про те, як це робиться, розповідається у наступній статті.

Object.create()

Стандарт ECMAScript 5 визначає метод Object.create(), який створює новий об'єкт і використовує свій перший аргумент як прототип цього об'єкта. Додатково Object.create() може приймати другий необов'язковий аргумент, який описує властивості нового об'єкта.

Object.create() є статичною функцією, а не методом, який викликається щодо деякого конкретного об'єкта. Щоб викликати цю функцію, достатньо передати їй бажаний об'єкт-прототип:

// obj успадковує властивості x та y var obj = Object.create((x:1, y:2));

Щоб створити об'єкт, що не має прототипу, можна передати значення null, але в цьому випадку новостворений об'єкт не успадкує жодних властивостей, ні базових методів, таких як toString() (а це означає, що цей об'єкт не можна буде використовувати у виразах з оператором +):

// obj2 не успадковує ні властивостей, ні методів var obj2 = Object.create(null);

Якщо у програмі потрібно створити звичайний порожній об'єкт (який, наприклад, повертається літералом () або виразом new Object()), передайте у першому аргументі Object.prototype:

// obj3 подібний до об'єкта, створеного // за допомогою () або new Object() var obj3 = Object.create(Object.prototype);

Можливість створювати нові об'єкти з довільними прототипами (скажімо інакше: можливість створювати спадкоємців від будь-яких об'єктів) є потужним інструментом, дію якого можна імітувати в ECMAScript 3 за допомогою функції, наведеної в прикладі нижче:

// inherit() повертає новостворений об'єкт, успадковуючи властивості // об'єкта-прототипу p. Використовує функцію Object.create() з ECMAScript 5, // якщо вона визначена, інакше використовується більш старий прийом. function inherit(p) ( if (p == null) throw TypeError(); // p не може бути значенням null if (Object.create) // Якщо Object.create() визначена... return Object.create(p ) // використовувати її var t = typeof p;// Інакше з'ясувати тип і перевірити його if (t !== "object" && t !== "function") throw TypeError(); // Визначити порожній конструктор f.prototype = p;// Записати в його властивість prototype // посилання на об'єкт p. return new f(); // Використовувати f() для створення // "спадкоємця" об'єкта p.

Реалізація функції inherit() набуде більше сенсу, як тільки ми познайомимося з конструкторами у статті. А поки що просто вважайте, що вона повертає новий об'єкт, що успадковує властивості об'єкта в аргументі. Зверніть увагу, що функція inherit() не є повноцінною заміною Object.create(): вона не дозволяє створювати об'єкти без прототипу і не приймає другий необов'язковий аргумент, як Object.create().

Отримання та зміна властивостей

Отримати значення властивості можна за допомогою операторів точки (.) та квадратних дужок (). Зліва від оператора має бути вираз, повертає об'єкт. При використанні оператора точки праворуч повинен бути простий ідентифікатор, що відповідає імені властивості. При використанні квадратних дужок у квадратних дужках має вказуватися вираз, що повертає рядок, що містить ім'я необхідної властивості:

// Простий об'єкт var user = (login:"kot86", name:"Alexandr", age:26); var login = user.login; // Отримати властивість "login" об'єкта user var name = user.name; // Отримати властивість "name" об'єкта user var age = user ["age"]; // Отримати властивість "age" об'єкта user

Щоб створити нову властивість або змінити значення існуючої властивості, також використовуються оператори точки та квадратні дужки, як в операціях читання значень властивостей, але сам вираз міститься вже зліва від оператора присвоєння:

User.age = 28; // Змінити значення якості "age" user["login"] = "kot84"; // Змінити значення якості "login" user["surname"] = "Frolov"; // Створити нову властивість "surname"

У ECMAScript 3 ідентифікатор, який слідує за точкою, не може бути зарезервованим словом: не можна записати звернення до властивості o.for або o.class, тому що for є ключовим словом, а class - словом, зарезервованим для використання в майбутньому.

Якщо об'єкт має властивості, імена яких збігаються із зарезервованими словами, для доступу до них необхідно використовувати форму запису з квадратними дужками: o["for"] та o["class"]. Стандарт ECMAScript 5 послаблює цю вимогу (як це вже зроблено в деяких реалізаціях ECMAScript 3) та допускає можливість використання зарезервованих слів після оператора точки.

Прототипи

Кожен об'єкт у мові JavaScript має другий об'єкт (або null, але значно рідше) асоційований з ним. Цей другий об'єкт називається прототипом і перший об'єкт успадковує від прототипу його властивості.

Всі об'єкти, створені за допомогою літералів об'єктів, мають той самий об'єкт-прототип, на який у програмі JavaScript можна послатися так: Object.prototype .

Об'єкти, створені за допомогою ключового слова new і виклику конструктора, як прототип отримують значення властивості prototype функції-конструктора. Тому об'єкт, створений виразом new Object(), успадковує властивості об'єкта Object.prototype, ніби він був створений за допомогою літералу у фігурних дужках (). Аналогічно прототипом об'єкта, створеного виразом new Array() є Array.prototype, а прототипом об'єкта, створеного виразом new Date(), є Date.prototype.

Object.prototype - одне з небагатьох об'єктів, які мають прототипу: він не має успадкованих властивостей. Інші об'єкти-прототипи є звичайними об'єктами, що мають власні прототипи.

Всі вбудовані конструктори (і більшість конструкторів) успадковують прототип Object.prototype. Наприклад, Date.prototype успадковує властивості від Object.prototype, тому об'єкт Date, створений виразом new Date(), успадковує властивості від обох прототипів, Date.prototype і Object.prototype. Така пов'язана послідовність об'єктів-прототипів називається ланцюжком прототипів.

успадкування

Об'єкти в мові JavaScript мають безліч «власних властивостей» і можуть також успадковувати безліч властивостей від об'єкта-прототипу. Щоб розібратися в цьому, необхідно уважно вивчити механізм доступу до властивостей. У прикладах розділу для створення об'єктів з певними прототипами використовується функція inherit(), показана вище.

Припустимо, що програма звертається до якості x об'єкта obj. Якщо об'єкт obj не має власної властивості з таким ім'ям, намагається відшукати властивість x у прототипі об'єкта obj. Якщо об'єкт-прототип немає власного властивості з цим ім'ям, але має власний прототип, намагається знайти властивість у прототипі прототипу. Так триває доти, доки знайдено властивість x чи доки досягне об'єкт, який має прототипу. Як бачите, атрибут prototype об'єкта створює ланцюжок або пов'язаний список об'єктів, від яких успадковуються властивості.

Var obj = (); // obj успадковує методи об'єкта Object.prototype obj.x = 1; // і має власну властивість x. var p = inherit(obj); // p успадковує властивості об'єктів obj та Object.prototype p.y = 2; // і має власну властивість y. var q = inherit(p); // q успадковує властивості об'єктів p, obj та Object.prototype q.z = 3; // і має власну властивість z. var s = q.toString(); // toString успадковується від Object.prototype var d = q.x + q.y // Результат 3: x та y успадковуються від obj і p

Тепер припустимо, що програма надає деяке значення якості x об'єкта obj. Якщо об'єкт obj має власну властивість (не успадковане) з ім'ям x, то операція присвоєння просто змінить значення існуючої властивості. В іншому випадку в об'єкті obj буде створено нову властивість з ім'ям x. Якщо раніше об'єкт obj успадковував властивість x, успадкована властивість тепер виявиться приховано новоствореною власною властивістю з тим самим ім'ям.

Операція присвоювання значення властивості перевірить наявність цієї властивості у ланцюжку прототипів, щоб переконатися у допустимості присвоювання. Наприклад, якщо об'єкт obj успадковує властивість x, доступне лише читання, то привласнення виконуватися нічого очікувати. Однак якщо привласнення допустиме, завжди створюється або змінюється властивість в оригінальному об'єкті і ніколи в ланцюжку прототипів. Той факт, що механізм успадкування діє під час читання властивостей, але з діє при запису нових значень, є ключовою особливістю мови JavaScript, тому що вона дозволяє вибірково перевизначати успадковані властивості:

Var unitcircle = (r:1); // Об'єкт, від якого успадковується властивість var c = inherit (unitcircle); // c успадковує властивість r c.x = 1; c.y = 1; // c визначає дві власні властивості c.r = 2; // c перевизначає успадковану властивість console.log(unitcircle.r); // => 1: об'єкт-прототип не змінився

Існує один виняток із цього правила, коли операція присвоювання значення властивості зазнає невдачі або призводить до створення/зміни властивості оригінального об'єкта. Якщо об'єкт obj успадковує властивість x і доступ до цієї властивості здійснюється за допомогою методів доступу, замість створення нової властивості x в об'єкті obj здійснюється виклик методу запису нового значення. Однак зверніть увагу, що метод запису викликається щодо об'єкта obj, а не щодо прототипу, в якому визначено цю властивість, тому, якщо метод запису визначає будь-які властивості, вони будуть створені в об'єкті obj, а ланцюжок прототипів знову залишиться незмінним.

Помилки доступу до властивостей

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

Спроба звернення до неіснуючого властивості не вважається помилкою. Якщо властивість x не буде знайдена серед власних або успадкованих властивостей об'єкта obj, вираз звернення до властивості obj.x поверне undefined.

Проте спроба звернутися до якості неіснуючого об'єкта вважається помилкою. Значення null і undefined не мають властивостей і спроби звернутися до властивостей цих значень вважаються помилкою:

// Простий об'єкт var user = (login:"kot86", name:"Alexandr", age:26); var a = user.password; // undefined: властивість відсутня // Збудить виняток TypeError. // Значення undefined немає властивості length var len = user.password.length;

Якщо немає впевненості, що user і user.password є об'єктами (або поводяться подібно до об'єктів), не можна використовувати вираз user.password.length, оскільки воно може порушити виняток. Нижче демонструються два способи захисту проти таких винятків:

// Більш наочний та прямолінійний спосіб var len = undefined; if (user) ( if (user.password) len = user.password.length; ) // Коротша і характерна для JavaScript альтернатива // отримання довжини значення властивості password var len = user && user.password && user.password.length ;

Спроби встановити значення властивості інших значень який завжди закінчуються успіхом: деякі властивості доступні лише читання і дозволяють змінювати їх значення. Крім того, деякі об'єкти не дозволяють додавати нові властивості. Однак найцікавіше, що подібні невдачі, як правило, не призводять до порушення винятку:

// Властивості prototype вбудованих конструкторів доступні лише читання Object.prototype = 0; // Присвоєння не порушить виняток; // значення Object.prototype не зміниться

Цей недолік JavaScript, що історично склався, виправлений в строгому режимі, що визначається стандартом ECMAScript 5. Всі невдалі спроби змінити значення властивості в строгому режимі призводять до виключення TypeError.

Правила, що дозволяють визначити, коли спроба виконати операцію присвоєння завершиться успіхом, а коли невдачею, прості та зрозумілі, але їх складно висловити у досить короткій формі. Спроба надати значення властивості p об'єкта obj зазнає невдачі в таких випадках:

    Об'єкт obj має власну властивість p, доступне лише читання: не можна змінити значення властивості, доступного лише читання. (Зверніть, однак, увагу на метод defineProperty(), який є винятком, що дозволяє змінювати значення властивостей, що настроюються, доступних тільки для читання.)

    Об'єкт obj має успадковану властивість p, доступну лише читання: успадковані властивості, доступні лише читання, неможливо перевизначити власними властивостями з тими самими іменами.

    Об'єкт obj немає власної властивості p; об'єкт obj не успадковує властивість p з методами доступу та атрибут extensible об'єкта obj має значення false. Якщо властивість p відсутня в об'єкті obj і йому не визначено метод запису, то операція присвоєння спробує додати властивість p в об'єкт obj. Але оскільки об'єкт obj не допускає можливість розширення, то спроба додати до нього нову властивість зазнає невдачі.

Видалення властивостей

Оператор deleteвидаляє властивість із об'єкта. Його єдиний операнд може бути виразом звернення до якості. Може здатися дивовижним, але оператор deleteне впливає значення властивості - він оперує самим властивістю:

// Простий об'єкт var user = (login:"kot86", name:"Alexandr", age:26); delete user.login; // Тепер об'єкт user немає властивості login delete user["name"]; // Тепер об'єкт user не має властивості name

Оператор delete видаляє лише власні властивості та не видаляє успадковані. (Щоб видалити успадковану властивість, необхідно видаляти його в об'єкті-прототипі, в якому воно визначено. Така операція торкнеться всіх об'єктів, що успадковують цей прототип.)

Вираз delete повертає значення true у разі успішного видалення властивості або коли операція видалення не призвела до зміни об'єкта (наприклад, при спробі видалити неіснуючу властивість). Вираз delete також повертає true, коли цьому оператору передається вираз, що не є виразом звернення до властивості:

Obj = (x: 1); // obj має власну властивість x і успадковує toString delete obj.x; // Видалить x і поверне true delete obj.x; // Нічого не зробить (x немає) і поверне true delete obj.toString; // Нічого не зробить (toString не власне властивість) і поверне true delete 1; // Безглуздо, але поверне true

Оператор delete не видаляє властивості, що не настроюються, атрибут configurableяких має значення false. (Однак він може видаляти налаштовуються властивості об'єктів, що не розширюються.) Ненастроюваними є властивості вбудованих об'єктів, а також властивості глобального об'єкта, створені за допомогою інструкцій оголошення змінних і функцій. Спроба видалити ненастроювану властивість у строгому режимі викликає виключення TypeError. У нестрогому режимі (і в реалізаціях ECMAScript 3) у таких випадках оператор delete просто повертає false:

Delete Object.prototype; // Видалення неможливе - неналаштовується властивість var x = 1; // Оголошення глобальної змінної delete this.x; // Це властивість не можна видалити function f() () // Оголошення глобальної функції delete this.f; // Цю властивість також не можна видалити

Перевірка існування властивостей

Об'єкти в мові JavaScript можна розглядати як множини властивостей, і нерідко буває корисно мати можливість перевірити приналежність до множини - перевірити наявність в об'єкті властивості з цим ім'ям. Виконати таку перевірку можна за допомогою оператора in, за допомогою методів hasOwnProperty()і propertyIsEnumerable()або просто звернувшись до якості.

Оператор in вимагає, щоб у лівому операнді йому було передано ім'я властивості (у вигляді рядка) та об'єкт у правому операнді. Він повертає true, якщо об'єкт має власну або успадковану властивість із цим ім'ям:

Var obj = (x: 1) "x" in obj; // true: obj має власну властивість "x" "y" in obj; // false: obj немає властивості "y" "toString" in obj; // true: obj успадковує властивість toString

Метод hasOwnProperty() об'єкта перевіряє, чи об'єкт має власну властивість із зазначеним ім'ям. Для успадкованих властивостей він повертає false:

Var obj = (x:1) obj.hasOwnProperty("x"); // true: obj має власну властивість "x" obj.hasOwnProperty("y"); // false: obj немає властивості "y" obj.hasOwnProperty("toString"); // false: toString - успадкована властивість

Метод propertyIsEnumerable() накладає додаткові обмеження проти hasOwnProperty(). Він повертає true, тільки якщо вказана властивість є власною властивістю, атрибут enumerable якого має значення true. Властивості вбудованих об'єктів є переліченими. Властивості, створені звичайною програмою на мові JavaScript, є перерахованими, якщо не був використаний один із методів ECMAScript 5, наведених нижче, які роблять властивості неперерахованими.

Часто замість оператора in достатньо використовувати простий вираз звернення до властивості та використовувати оператор!== для перевірки на нерівність значенню undefined:

Var obj = (x: 1) obj.x !== undefined; // true: obj має властивість "x" obj.y! == undefined; // false: obj не має властивості "y" obj.toString! == undefined; // true: obj успадковує властивість toString

Однак оператор in відрізняє ситуації, які не відрізняються при використанні наведеного вище прийому на основі звернення до властивості. Оператор in відрізняє відсутність властивості від властивості, що має значення undefined.

Перелік властивостей

Замість перевірки наявності окремих властивостейіноді буває необхідно обійти всі наявні властивості або одержати список всіх властивостей об'єкта. Зазвичай використовується цикл for/in, проте стандарт ECMAScript 5 надає дві зручні альтернативи.

Інструкція циклу for/in виконує тіло циклу для кожного перерахованого властивості (власного або успадкованого) зазначеного об'єкта, присвоюючи ім'я властивості змінної циклу. Вбудовані методи, що успадковуються об'єктами, є неперелічуваними, а властивості, що додаються в об'єкти вашою програмою, є перерахованими (якщо не використовувалися функції, що описуються нижче, що дозволяють зробити властивості непереліченими). Наприклад:

// Простий об'єкт з трьома властивостями, що перераховуються var user = ( login:"kot86", name:"Alexandr", age:26 ); user.propertyIsEnumerable("toString"); // false, toString - вбудований метод for(n in user) console.log(n);

Деякі бібліотеки додають нові методи (або інші властивості) в об'єкт Object.prototype, щоб вони могли бути успадковані і доступні всім об'єктам. Однак до появи стандарту ECMAScript 5 була відсутня можливість зробити ці додаткові методинеперелічуваними, тому вони виявлялися доступними для перерахування циклах for/in. Щоб вирішити цю проблему, може знадобитися фільтрувати властивості, що повертаються циклом for/in. Нижче наводяться два приклади реалізації такої фільтрації:

For (n in user) ( if (!user.hasOwnProperty(n)) continue; console.log(n); ) for (n in user) ( if (typeof user[n] === "function") continue; console.log(n); )

На додаток до циклу for/in стандарт ECMAScript 5 визначає дві функції, що перераховують імена властивостей. Перша з них, Object.keys(), Повертає масив власних назв перерахованих властивостей об'єкта.

Друга функція ECMAScript 5, яка виконує перелік властивостей - Object.getOwnPropertyNames(). Вона діє подібно до функції Object.keys(), але повертає імена всіх власних властивостей зазначеного об'єкта, а не тільки перераховані. У реалізаціях ECMAScript 3 немає можливості реалізувати подібні функції, тому що ECMAScript 3 не передбачає можливість отримання неперелічуваних властивостей об'єкта.

Методи читання та запису властивостей

Вище говорилося, що властивість об'єкта має ім'я, значення і набір атрибутів. У ECMAScript 5 значення може заміщуватися одним або двома методами, відомими як методи читання (getter)і записи (setter). Властивості, для яких визначаються методи читання та запису, іноді називають властивостями з методами доступу, щоб відрізняти їх від властивостей з даними, що становлять просте значення.

Коли програма намагається отримати значення якості з методами доступу, інтерпретатор викликає метод читання (без аргументів). Значення, що повертається цим методом, стає значенням вираження звернення до властивості. Коли програма намагається записати значення властивість, інтерпретатор викликає метод запису, передаючи йому значення, що знаходиться праворуч від оператора присвоювання. Цей спосіб відповідає за «установку» значення якості. Значення, яке повертається методом запису, ігнорується.

На відміну від властивостей даних, властивості з методами доступу немає атрибута writable. Якщо властивість має обидва методи, читання та записи, вона доступна для читання/запису. Якщо властивість має лише метод читання, вона доступна лише читання. А якщо властивість має тільки метод запису, воно доступне тільки для запису (таке неможливе для властивостей з даними) і спроби прочитати значення такої властивості завжди повертатимуть undefined.

Найпростіший спосіб визначити властивість з методами доступу полягає у використанні розширеного синтаксису визначення літералів об'єктів:

Var obj = ( // Звичайна властивість з даними data_prop: value, // Властивість з методами доступу визначається як пара функцій get accessor_prop() ( /* тіло функції */ ), set accessor_prop(value) ( ​​/* тіло функції */ ) );

Властивості з методами доступу визначаються як одна або дві функції, імена яких збігаються з ім'ям властивості та із заміною ключового слова function на get та/або set.

Зверніть увагу, що не потрібно використовувати двокрапку для відокремлення імені властивості від функції, що управляє доступом до властивості, але, як і раніше, необхідно використовувати кому після тіла функції, щоб відокремити метод від інших методів або властивостей з даними.

Наприклад розглянемо наступний об'єкт, що представляє декартові координатикрапки на площині. Для представлення координат X і Y в ньому є звичайні властивості даних, а також властивості з методами доступу, що дозволяють отримати еквівалентні полярні координати точки:

Var p = ( // x і y звичайні властивості з даними, доступні для читання/запису x: 1.0, y: 1.0, // r - доступна для читання/запису властивість з двома методами доступу. // Не забувайте додавати коми після методів доступу get r() ( return Math.sqrt(this.x*this.x + this.y*this.y); ), set r(newvalue) ( ​​var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y);var ratio = newvalue/oldvalue;this.x *= ratio; this.y *= ratio; ), // theta - доступна тільки для читання властивість з єдиним методомчитання get theta() ( return Math.atan2(this.y, this.x); ) );

Зверніть увагу на використання цього ключового слова в методах читання і запису вище. Інтерпретатор викликатиме ці функції, як методи об'єкта, у якому вони визначені, тобто. У тілі функції це буде посилатися на об'єкт точки. Завдяки цьому метод читання властивості r може посилатися на властивості x та y, як this.x та this.y.

Властивості з методами доступу успадковуються так само, як звичайні властивості даних, тому об'єкт p, визначений вище, можна використовувати як прототип для інших об'єктів точок. У нових об'єктах можна визначати власні властивості x та y, і вони успадкуватимуть властивості r та theta.

Атрибути об'єкту

Всі об'єкти мають атрибути prototype, class і extensible. Всі ці атрибути описуються в нижченаведених підрозділах.

Атрибут prototype

Атрибут prototype об'єкта визначає об'єкт, від якого успадковуються властивості. Важливо розуміти, що у програмному коді зустрічається посилання prototype, вона позначає звичайне властивість об'єкта, а чи не атрибут prototype.

Атрибут prototype встановлюється під час створення об'єкта. Для об'єктів, створених за допомогою літералів, прототипом є Object.prototype. p align="justify"> Прототипом об'єкта, створеного за допомогою оператора new, є значення властивості prototype конструктора. А прототипом об'єкта, створеного за допомогою Object.create() стає перший аргумент цієї функції (який може мати значення null).

Стандартом ECMAScript 5 передбачається визначити прототип будь-якого об'єкта, якщо передати його методу Object.getPrototypeOf(). У ECMAScript 3 немає еквівалентної функції, але найчастіше визначити прототип об'єкта obj можна за допомогою виразу obj.constructor.prototype.

Об'єкти, створені за допомогою оператора new, зазвичай успадковують властивість constructor, що посилається на функцію-конструктор, використану для створення об'єкта І як говорилося вище, функції-конструктори мають властивість prototype, яке визначає прототип об'єктів, створених з допомогою цього конструктора.

Зверніть увагу, що об'єкти, створені за допомогою літералів об'єктів або Object.create(), одержують властивість конструктора, яка посилається на конструктор Object(). Таким чином, constructor.prototype посилається на справжній прототип для літералів об'єктів, але це зазвичай не так для об'єктів, створених викликом Object.create().

Щоб визначити, чи є один об'єкт прототипом (або ланкою в ланцюжку прототипів) іншого об'єкта, слід використовувати метод isPrototypeOf(). Щоб дізнатися, чи є p-прототипом obj, потрібно записати вираз p.isPrototypeOf(obj). Наприклад:

Var p = (x: 1); // Визначити об'єкт-прототип. var obj = Object.create(p); // Створити об'єкт із цим прототипом. p.isPrototypeOf(obj); // => true: obj успадковує p Object.prototype.isPrototypeOf(p); // => true: p успадковує Object.prototype

Атрибут class

Атрибут classОб'єкт - це рядок, що містить інформацію про тип об'єкта. Ні ECMAScript 3, ні ECMAScript 5 не передбачається можливість зміни цього атрибуту і надаються лише непрямі способи визначення його значення. За умовчанням метод toString() (успадкований від Object.prototype) повертає рядок виду:

Тому, щоб визначити клас об'єкта, можна спробувати викликати метод toString() цього об'єкта і витягти з результату підрядок з восьмого до передостаннього символу. Вся хитрість полягає в тому, що багато методів успадковують інші, більш корисні реалізації методу toString(), і щоб викликати потрібну версію toString(), необхідно здійснити опосередкований виклик за допомогою методу Function.call().

У прикладі нижче визначається функція, яка повертає клас будь-якого об'єкта, переданого їй:

// Назва класу об'єкта function classof(obj) ( if (obj === null) return "Null"; if (obj === undefined) return "Undefined"; return Object.prototype.toString.call(obj).slice (8,-1);

Цій функції classof() можна передати будь-яке значення, допустиме у JavaScript. Числа, рядки та логічні значення діють подібно до об'єктів, коли щодо них викликається метод toString(), а значення null і undefined обробляються особливо.

Атрибут extensible

Атрибут extensible об'єкта визначає, чи можна додавати в об'єкт нові властивості. У ECMAScript 3 усі вбудовані та обумовлені користувачем об'єкти неявно допускали можливість розширення, а розширюваність об'єктів середовища виконання визначалася кожною конкретною реалізацією. У ECMAScript 5 всі об'єкти, що вбудовуються та визначаються користувачем, розширюються, якщо вони не були перетворені на об'єкти, що не розширюються, а розширюваність об'єктів середовища виконання, як і раніше, визначається кожною конкретною реалізацією.

Стандарт ECMAScript 5 визначає функції отримання та зміни ознаки розширюваності об'єкта. Щоб визначити, чи допускається розширювати об'єкт, його слід передати методом Object.isExtensible(). Щоб зробити об'єкт нерозширюваним, його потрібно передати методом Object.preventExtensions(). Зверніть увагу, що після того, як об'єкт буде зроблений нерозширюваним, його не можна знову зробити розширюваним. Зауважте також, що виклик preventExtensions() впливає лише на розширюваність самого об'єкта. Якщо нові властивості додати в прототип об'єкта, що не розширюється, об'єкт, що не розширюється, успадкує ці нові властивості.

Призначення атрибуту extensible у тому, щоб дати можливість «фіксувати» об'єкти у певному стані, заборонивши внесення змін. Атрибут об'єктів extensible часто використовується спільно з атрибутами властивостей configurable та writable, тому в ECMAScript 5 визначаються функції, що спрощують одночасне встановлення цих атрибутів.

Метод Object.seal()діє подібно до методу Object.preventExtensions(), але він не тільки робить об'єкт нерозширюваним, але і робить всі властивості цього об'єкта недоступними для налаштування. Тобто до об'єкта не можна буде додати нові властивості, а існуючі властивості не можна буде видалити або налаштувати. Однак існуючі властивості, доступні для запису, можуть бути змінені.

Після виклику Object.seal() об'єкт не можна буде повернути до попереднього стану. Щоб визначити, чи викликався метод Object.seal() для об'єкта, можна викликати метод Object.isSealed().

Метод Object.freeze()забезпечує ще жорсткішу фіксацію об'єктів. Крім того, що він робить об'єкт нерозширюваним, а його властивості недоступними для налаштування, він також робить усі власні властивості з даними доступними лише для читання. (Це не стосується властивостей об'єкта з методами доступу, що володіють методами запису; ці методи, як і раніше, будуть викликатися інструкціями присвоєння.) Щоб визначити, чи викликався метод Object.freeze() об'єкта, можна викликати метод Object.isFrozen().

Важливо розуміти, що Object.seal() і Object.freeze() впливають лише на об'єкт, який їм передається: вони не торкаються прототипу цього об'єкта. Якщо в програмі потрібно повністю зафіксувати об'єкт, вам, ймовірно, потрібно зафіксувати об'єкти в ланцюжку прототипів.

Серіалізація об'єктів

Серіалізація об'єктів - це процес перетворення об'єктів у рядкову форму подання, яка може використовуватися їх відновлення. Для серіалізації та відновлення об'єктів JavaScript стандартом ECMAScript 5 надаються вбудовані функції JSON.stringify()і JSON.parse(). Ці функції використовують формат обміну даними JSON. Назва JSON походить від "JavaScript Object Notation" (форма запису об'єктів JavaScript), а синтаксис цієї форми запису нагадує синтаксис літералів об'єктів та масивів у мові JavaScript:

Var obj = (x: 1, y: (z:)); // Визначити випробувальний об'єкт var s = JSON.stringify (obj); // s == "("x":1,"y":("z":))" var p = JSON.parse(s); // p - копія об'єкта obj

Синтаксис формату JSON є лише підмножиною синтаксису мови JavaScript і не може використовуватися для представлення всіх можливих значень, допустимих JavaScript. Підтримуються та можуть бути серіалізовані та відновлені: об'єкти, масиви, рядки, кінцеві числові значення, true, false та null. Значення NaN, Infinity та -Infinity серіалізуються у значення null. Об'єкти Date серіалізуються в рядки з датами формат ISO, але JSON.parse() залишає їх у рядковому поданні та не відновлює початкові об'єкти Date.

Об'єкти Function, RegExp і Error і undefined значення не можуть бути серіалізовані або відновлені. Функція JSON.stringify() серіалізує лише власні властивості об'єкта, що перераховуються. Якщо значення властивості може бути серіалізоване, ця властивість просто виключається з рядкового представлення. Обидві функції, JSON.stringify() і JSON.parse(), приймають необов'язковий другий аргумент, який можна використовувати для налаштування процесу серіалізації та/або відновлення, наприклад, шляхом визначення списку властивостей, що підлягають серіалізації, або функції перетворення значень під час серіалізації.

Відвідування веб-ресурсу - це конкретний URI в адресному рядкубраузер. Відвідувач вказує адресу сторінки і вона розбирається браузером на елементи дерева DOM - Document Object Model. Будь-яке посилання на цій сторінці вказує браузеру розібрати іншу сторінку та побудувати інше дерево об'єктів.

Браузер дозволяє відвідувачеві повернутися назад або пройти вперед ланцюжком сторінок, які вже були переглянуті в поточному сеансі роботи.

Фактично дії користувача – це переміщення між системами об'єктів, що утворюються у процесі відвідування сторінок. Кожна сторінка - це власне дерево DOM і, крім того, JavaScript object"s - це об'єкти синтаксису самої мови та описів користувача.

DOM: завантаження, оновлення та зміна

Є три основні варіанти, які формують об'єкти сторінки веб-ресурсу, як на рівні DOM і самої мови JavaScript, що виконала конструкції створення змінних, так і на підставі описів, зроблених розробником:

  • завантаження – відвідувач прийшов на сторінку сайту;
  • оновлення – відвідувач (кнопка браузера або Ctrl-F5);
  • зміна елемента сторінки, наприклад (AJAX, скрипт, подія, ...).

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

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

Зміна сторінки без перезавантаження на рівні окремого елемента (наприклад, AJAX) - це звичайне рішеннядля динамічних сторінок Як правило, це використовується для переходів елементами сторінки, зміни її об'єктів, управління діалогом з відвідувачем.

Фундаментальні об'єкти JavaScript

JavaScript ґрунтується на об'єктах. Практично все змінні мови– це об'єкти. Розробник може формулювати власні описиоб'єктів, використовуючи різноманітні варіанти синтаксису.

Все, що не є "рядком", "числом", true, false, null або undefined, є об'єктом. У рамках синтаксису мови цьому можна не надавати значення, розуміючи під об'єктами лише елементи DOM та власні опис JavaScript Object"s. Фундаментальна будова мови в більшості випадків для розробника не має суттєвого практичного значення.

Наприклад, математичні функції представлені об'єктом Math. Це зручно в рамках концепції мови, але для розробника це просто зручний синтаксис використання необхідного арсеналу математичних операцій.

Важливо правильно працювати з DOM та коректно описувати власні об'єкти. Синтаксис JavaScript object function's і виразів їх застосування - це форма запису логіки необхідного алгоритму.

Рядки, масиви та об'єкти

В основі всіх об'єктів JavaScript лежить правило: "властивість" = "значення" та поняття асоціативного масиву. В самому простому випадку object JavaScript - це сукупність пар "властивість" = "значення". У цьому " значення " який завжди може бути числом, а властивість який завжди записано без лапок.

Не слід зловживати ім'ям якостей. Ідеально, коли імена властивостей містять лише символи латинського алфавіту, задовольняють вимогам до іменування змінних і є ключовими (в т. ч. зарезервованими) словами мови.

Жодного впорядкування властивостей не передбачається, але при створенні або ініціалізації асоціативного масиву знати, як розташовані його елементи, цілком допустимо. Використовувати цю обставину не рекомендується, але мати на увазі – можливо.

Ініціалізувати масив властивостей означає одночасно:

  • створення масиву;
  • створення об'єкта.

У конкретному контексті застосування можна розглядати JavaScript object – як асоціативний масив, а в іншому місці алгоритму – як об'єкт, призначати йому потрібні методи, змінювати значення його елементів.

Оскільки імена властивостей та їх значення при створенні або зміні повинні задаватися у форматі рядків, рекомендується використовувати малу нотацію та лапки.

Доступ до властивостей об'єкту

Отримати та змінити значення властивостей об'єкта можна конструкцією Object.keys: JavaScript формує масив усіх властивостей об'єкта. Коли об'єкти створюються динамічно, ця конструкція дуже зручна, оскільки автоматично формує список всіх властивостей, що є в об'єкті.

У цьому прикладі виконано опис двох масивів по-різному. У застосуванні обидва масиви еквівалентні, оскільки містять однойменні властивості та їх значення. У циклі перебираються всі властивості другого масиву та формується рядок усіх значень.

Аналогічного ефекту можна досягти в точковій нотації або скобковій:

  • x1_Obj .NameLast;
  • x1_Obj ["NameFirst"].

Обидві конструкції допустимі та дають потрібний результат. У наведеному прикладі при завданні масиву через фігурні дужки "()" може бути допущена помилка у вигляді символу "," в кінці перерахування (позначено у прикладі червоним кружечком). Зазвичай браузери ігнорують зайвий символ у перерахуванні, але краще не робити.

Видалення властивостей об'єкту

Оскільки об'єкт - це асоціативний масив, операція JavaScript delete object виконується лише на рівні поточного об'єкта (при успадкування - це має значення) і на колекції властивостей цього об'єкта.

У контексті наведеного прикладу можна використовувати такі конструкції:

  • delete x1_Obj .NameLast ;
  • delete x2_Obj ["NameFirst"];

Перша конструкція видаляє другий елемент першого об'єкта, друга конструкція – перший елемент другого об'єкта. Оператор видалення не працює на властивості прототипу і повертає результатом значення false, якщо властивість не може бути видалена.

Властивості та методи об'єктів

Синтаксис JavaScript object properties та functions (методи) аналогічний загальним канонам синтаксису та семантики мови. По суті, справа якраз навпаки.

Властивості та методи об'єкта - це варіант опису інформації та дій, що допускаються з нею, через об'єктно-орієнтовану парадигму JavaScript.

У цьому прикладі описаний об'єкт x3_Obj, який має лише дві властивості: item і pos. Потім було додано метод hello() як функції. В результаті інтерпретацію цього опису в контексті значень властивостей JavaScript object values ​​зробить так, як показано в віконці результату, тобто помістить тіло функції (1) як значення.

При прямому виклику властивості Hello() воно інтерпретується як метод (функція) і результатом (2) виконання коду цього методу.

Ключове слово this в об'єкті

Для орієнтації в просторі властивостей об'єкта розробник може використовувати ключове слово цього і посилатися через нього на описані ним властивості для отримання або зміни їх значень.

Це тільки початок опису об'єкта з тілом конструктора. У цьому прикладі описано об'єкт для роботи з куками. Об'єкт ініціалізується в момент завантаження сторінки конструкцією:

  • var oCookie = new scCookies (cOwnerCode);
  • oCookie .Init();

У цьому прикладі cOwnerCode – унікальний код відвідувача. Якщо його немає, то в конструкторі об'єкта oCookie буде створено новий код. Неважливо, що мав на увазі під авторизацією відвідувача розробник даного об'єкта, важливо як ключове слово цього використовується для опису методів об'єкта та їх виклику з інших методів об'єкта:

  • this .GetCookie = function (cName) ( ... );
  • this .SetCookie = function (cName, cValue) ( ​​... ).

Так описано методи об'єкта для читання куки по її імені та запису значення куки з конкретним ім'ям.

  • this .GetCookie ("cOwner");
  • this .SetCookie ("cOwner", cOwner);

Так вони використовуються, якщо в результаті першої конструкції значення не буде представлено, друга конструкція його встановлює.

Приклад об'єкта для роботи з куками

Можна обговорювати, Object і парадигма об'єктно-орієнтованого підходу мови, що працює в середовищі браузера. Це цікаво, але в реальності потрібна практика, а не теорія. DOM сторінки, надавати інструментарій для маніпулювання об'єктами та переміщення систем об'єктів - це сильна сторона JavaScript.

На об'єктно-орієнтованій практиці важливе інше. Робота з куками практично на всіх веб-ресурсах гаразд. Реалізувати це у форматі об'єкта – чудова ідея. У цьому контексті ініціалізація об'єкта відбувається в момент відкриття сторінки: сторінка завантажена = об'єкт cookie існує і все прочитав, а чого не було - створив.

У процесі роботи зі сторінкою відвідувач здійснює ті чи інші дії і браузер повинен змінити чи створити куки. Існують два методи об'єкта (позначені вище), які це роблять.

Фактично об'єкт cookie виникає відразу після того, як браузер побудує DOM і доповнює систему об'єктів JavaScript новим функціоналом: прочитати та створити (змінити) cookie.

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

При такому підході розробник забезпечує створення системи унікальних об'єктів достатніх для опису та обслуговування задачі, що вирішується.

Події сторінки та об'єктів

Важливий елемент функціонування DOM та JavaScript: object event"s - дозволяє отримати інформацію про подію в його обробнику. Практично кожному елементу сторінки можна призначити власний обробник на одну або кілька подій.

Фактично розробник JavaScript створює не один великий шматок коду, а безліч описів функцій, об'єктів, структур даних і призначає конкретним елементамсторінки обробники подій.

Object event - це інформація про подію, що викликало обробник та можливість виконання цим обробником адекватної реакції на цю подію. Кожна подія відрізняється не тільки ім'ям та місцем виникнення, але й безліччю інших параметрів.

Зокрема, події клавіатури – це один набір параметрів, події мишки – зовсім інший спектр даних, а відповідь сервера через AJAX планує сам розробник.

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

Створення та робота об'єктів

Браузер "трансформує" URI, адресу веб-ресурсу, вказану відвідувачем, у дерево DOM - систему об'єктів сторінки цього веб-ресурсу. Переміщаючи відвідувача за посиланнями сторінки, браузер переходить на відповідні дерева інших сторінок.

Ця обставина дозволяє розробнику побудувати свою систему об'єктів як фундамент веб-ресурсу, який адекватно реагує на поведінку відвідувача. Якщо вичленувати загальний функціонал, наприклад:

  • робота з куками;
  • прийом/передача даних (AJAX);
  • спливаючі підказки;
  • внутрішні повідомлення (чат сайту);
  • інші завдання;

то, створені одного разу, системи об'єктів можна використовувати для розробки інших сайтів. У цьому суттєва перевага об'єктного підходу перед звичайним застосуванням JavaScript як мови браузера, що забезпечує функціонування сторінки та реакцію на події.

Об'єкти - це закінчені компоненти, які можна оформляти як окремих файлів і використовувати надалі. Характерною особливістю такого підходу є можливість зворотного зв'язку, коли оновлений, покращений об'єкт може використовуватися в попередній розробці, автоматично оновлюючи її функціонал без доопрацювання сайту.