Javascript Object: создание объектов и работа. JavaScript: Объекты

Объекты JavaScript

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

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

Давайте проиллюстрируем это на примере: Персона (person) - это объект. Свойства - это значения, ассоциированные с объектом. Свойства персоны включают имя, рост, вес, возраст, цвет кожи, цвет глаз, и т.д. Все персоны имеют эти свойства, но значения этих свойств будут различаться от одной персоны к другой. Объекты также имеют методы. Методы - это действия, которые могут быть выполнены над объектами. Методы персоны могут включать eat() - есть, sleep() - спать, work() - работать, play() - играть, и т.д.

Свойства

Синтаксис доступа к свойству объекта:

Код выше сгенерирует следующий вывод:

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

Пример вызова метода sleep() объекта personObj:

альтернативный синтаксис (использование объектных литералов):

2. Создание конструктора объекта

Создаем функцию, которая инициализирует объекты:

function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
}

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

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

Заметьте, что методы - это обычные функции, прикрепленные к объектам. Далее мы должны написать тело функции newlastname().

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

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

Что из себя представляет объект в JavaScript и какими возможностями обладает?

В js объектами являются простые ассоциативные массивы (их еще также называют хэшами).

Что же такое ассоциативный массив?

Это структура данных, в которой хранится какое-то количество информации, относящееся и описывающее определенный элемент. Все данные структурированы и связаны между собой как «ключ =>значение».

К примеру, вам нужно описать автомобили. Тогда вы создаете объект avto и описываете в массиве его характеристики. Я решил описать марку машины (name), ее цвет (color) и стоимость (price). Ниже я прикрепил код реализации описанного задания.

1 2 3 4 5 var avto = { name: "BMW 116i", color: "black", price: 588000 };

var avto = { name: "BMW 116i", color: "black", price: 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 = { name: "BMW 116i", color: "black", price: 588000 }; for (var obj in object) { alert(obj + ":" + object) }

var avto = { name: "BMW 116i", color: "black", price: 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 можно создавать свои собственные конструкторы и после использовать их для объявления новых объектов.

Итак, я хочу «смастерить» пользовательский конструктор для уже родных автомобилей. Заметьте, что имя надо писать с большой буквы. Это отличительная черта функций. Для этого я пишу вот такую программную реализацию:

function Avto (name, price) {

this.name = name;

this.price = price;

Теперь при создании неограниченного количества объектов и применения к ним этого конструктора, все они будут относиться к одному классу. Например:

var car1 = new Avto («BMW», 650000);

var car2 = new Avto («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 - всё объект». Технически это не совсем верно, однако производит должное впечатление на новичков:)

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

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

Итак, в JavaScript есть 6 базовых типов данных - это Undefined (обозначающий отсутствие значения), Null, Boolean (булев тип), String (строка), Number (число) и Object (объект).
При этом первые 5 являются примитивными типами данных, а Object - нет. Кроме того, условно можно считать, что у типа Object есть «подтипы»: массив (Array), функция (Function), регулярное выражение (RegExp) и другие.
Это несколько упрощенное описание, но на практике обычно достаточное.

Кроме того, примитивные типы String, Number и Boolean определенным образом связаны с не-примитивными «подтипами» Object: String, Number и Boolean соответственно.
Это означает, что строку "Hello, world", например, можно создать и как примитивное значение, и как объект типа String.
Если вкратце, то это сделано для того, чтобы программист мог и в работе с примитивными значениями использовать методы и свойства, как будто это объекты. А подробнее об этом можно будет прочитать в соответствующем разделе данной статьи.

Работа по ссылке

Ссылка - это средство доступа к объекту под различными именами. Работа с любыми объектами ведется исключительно по ссылке.
Продемонстрируем это на примере:
test=function () {alert("Hello!" )} //Создадим функцию {alert("Hello!")} (а функция, как мы помним, является полноправным объектом) и сделаем переменную test ссылкой на нее
test_link=test; //test_link теперь тоже ссылается на нашу функцию
test(); //Hello!
test_link(); //Hello!


Как мы видим, и первая ссылка, и вторая дают один и тот же результат.
Необходимо осознать, что у нас нет никакой функции с именем test, и что переменная test не является какой-то «главной» или «основной» ссылкой, а «test_link» - второстепенной.

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

Посмотрим, почему так важно это понимать:

test={prop: "sometext" } //Создаем объект со свойством prop
test_link=test; //Создаем еще одну ссылку на этот объект

Alert(test.prop); //sometext

//Изменяем свойство объекта
test_link.prop="newtext" ;

Alert(test.prop); //newtext
alert(test_link.prop); //newtext
/*Можно было бы сказать, что свойство изменилось и там и тут - но это не так.
Объект-то один. Так что свойство изменилось в нем один раз, а ссылки просто продолжают указывать туда, куда и указывают. */

//Добавляем новое свойство и удаляем старое
test.new_prop="hello" ;
delete test.prop;

Alert(test_link.prop); //undefined - такого свойства больше нет
alert(test_link.new_prop);

//Удаляем ссылку
delete test;
alert(test.new_prop);
/*В этом месте скрипт выкинет ошибку, потому что test уже не существует, и test.new_prop не существует тем более */
alert(test_link.new_prop); //hello
/* а вот тут все в порядке, ведь мы удалили не сам объект, а лишь ссылку на него. Теперь на наш объект указывает единственная ссылка test_link */

//Создаем новый объект
test=test_link; //Сперва снова создадим ссылку test
test_link={prop: "sometext" } //А вот и новый объект

Alert(test_link.prop); //sometext
alert(test.prop); //undefined
/* Cоздание нового объекта разрывает ссылочную связь, и теперь test и test_link указывают на разные объекты.
Фактически, это равносильно удалению ссылки test_link и созданию ее заново, но уже указывающей на другой объект */
alert(test.new_prop); //hello - теперь test содержит ссылку на наш самый первый объект


* This source code was highlighted with Source Code Highlighter .

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

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

Примитивные значения

Как я упоминал выше, типы данных String и Number могут быть как объектами, так и примитивными значениями.
obj=new String("hello" ); //Создаем строку как объект
simple="hello" ; //Создаем примитивное значение

Alert(obj); //hello
alert(simple); //hello - пока все предсказуемо

Alert(obj.length); //6 - у объекта типа String есть свойство length, хранящее длину строки
alert(simple.length); //6
/* Хотя simple - не объект, мы можем обращаться к тому же набору свойств, что и у объекта типа String. Это довольно удобно */

Obj.prop="text" ;
simple.prop="text" ;

Alert(obj.prop); //text - раз obj обычный объект, то мы можем запросто придать ему еще одно свойство
alert(simple.prop); //undefined - а вот simple не объект, и этот номер у нас не пройдет

* This source code was highlighted with Source Code Highlighter .


Все то же самое справедливо и для типа Number, и для Boolean (ну, кроме того, что в них нет свойства length, а есть ряд других замечательных свойств).
Использование строк и чисел как объектов не несет в себе никакой практической пользы, т.к. примитивные значения удобнее в работе, но сохраняют при этом весь необходимый функционал. Тем не менее, для полноты картины необходимо понимать этот механизм.

Не стоит путать использование примитивных значений с использованием литералов - например, независимо от того, создаем мы массив как «test=new Array()» или как «test=», в результате все равно будет один и тот же объект. Никаких примитивных значений мы не получим.

Создание и использование объектов

Итак, в отличии от языков, где реализована класс-объектная парадигма, нам не нужно создавать сначала класс, чтобы потом создать объект класса. Мы можем сразу создать объект, что и сделаем в следующем примере:
test={
simple_property: "Hello" ,
object_property: {
user_1: "Петя" ,
user_2: "Вася"
},
function_property: function (user) {
alert(this .simple_property + ", " + this .object_property);
}
}

Test.function_property("user_1" ); //Hello, Петя.

* This source code was highlighted with Source Code Highlighter .


Перед нами объект test, имеющий 3 свойства, названия которых, как я надеюсь, говорят сами за себя. Больше всего нас в нем интересует свойство function_property, содержащее функцию. Такую функцию можно назвать методом объекта.

В нашей функции дважды используется ключевое слово this, которое является указателем (т.е. ссылкой) на объект, из которого вызывается функция. Таким образом, this.simple_property=test.simple_property="Hello", а this.object_property=test.object_property="Петя".

Необходимо четко осознавать, this всегда указывает именно на объект, из которого вызвана функция, а не на объект, к которому она принадлежит. Хотя в данном примере это один и тот же объект, это не всегда так.

test.function_property("user_1" ); //Hello, Петя.

Test2=new Object(); //Еще одна форма создания нового объекта, аналогичная test2={}

Test.function_property.call(test2, "user_1" ); //ошибка
/* Метод call позволяет вызвать функцию от имени другого объекта. В данном случае, мы вызываем метод function_property объекта test, и его this указывает уже не на объект test, а на объект test2. А т.к. в нем нет свойства object_property, то при попытке получить this.object_propertyскрипт выдаст ошибку */

//попробуем исправить ситуацию
test2.simple_property="Good day" ;
test2.object_property=test.object_property; //В данном случае воспользуемся указанием объекта по ссылке, чтобы не дублировать код

Test.function_property.call(test2, "user_1" ); //Good day, Петя.


* This source code was highlighted with Source Code Highlighter .

Из примера также должно быть видно, что нет четких этапов создания и использования объекта. Объект может быть как угодно модифицирован в любое время - до, после и даже во время использования. Это тоже важное отличие от «традиционного» ООП.

Конструктор

В примере выше мы создавали 2 объекта, обладающих некой схожестью. И там и там имелись свойства simple_property и object_property. Очевидно, что при написании реального кода также нередко встает задача создания одинаковых или просто похожих объектов. И разумеется, мы не должны каждый такой объект создавать вручную.

На помощь нам придет конструктор. Конструктор в JavaScript - это не часть класса (потому что здесь нет классов), а просто самостоятельная функция. Самая обычная функция.

make_me=function (_name) {
alert("меня запустили" );
this .name=_name;

}


/* Давайте разберемся, что здесь происходит. Интерпретатор видит оператор new и проверяет, что находится справа от него. Т.к. make_me - это функция, и она может быть использована в качестве контруктора, то создается новый объект в памяти и запускается на выполнение функция make_me, причем ее this указывает как раз на этот новый объект. Далее этому объекту добавляется свойство name, которому присваивается значение из аргумента _name, и метод show_name. Также (не знаю в какой именно момент, но это и не важно) переменная child начинает указывать на наш новенький, только что рожденный объект */

Alert(child.name); //Вася
child.show_name(); //Вася


child2.show_name(); //Петя

Child2.show_name=function () {alert("Не буду говорить свое имя" );} //Не забываем, что можем изменять наши объекты в любой момент
child2.show_name(); //Не буду говорить свое имя

Child.show_name(); //Вася - дети никак не влияют друг на друга


* This source code was highlighted with Source Code Highlighter .

Также можно сравнить конструктора с отцом - он порождает ребенка, наделяя его определенными качествами, но сразу после создания ребенок становится полностью независим от родителя и может стать очень непохожим на своих братьев.
Если мы вспомним про описание типов данных в начале статьи, то становится понятно, что Object и его подтипы (Function, Array и другие) - это на самом деле конструкторы, придающие создаваемому объекту возможности функции, массива и т.д.

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

Прототип

Как у каждого ребенка есть отец и мать (хотя бы в биологическом смысле), также они есть и у каждого объекта в JavaScript. И если отец, как мы определелись, работает конструктором, то мать - это как раз прототип. Посмотрим, как это происходит:
make_me=function (_name) {
alert("меня запустили" );
this .name=_name;
this .show_name=function () {alert(this .name);}
}
/*
Видя ключевое слово function, интерпретатор проверяет код справа от него, и т.к. все ок - создает новый объект в памяти, который одновременно является нашей функцией. Затем, автоматически (без участия программиста) для этой функции создается свойство prototype, ссылающееся на пустой объект. Если бы мы это делали вручную, это выглядело бы как make_me.prototype=new Object();

Затем, данному объекту (на который указывает свойство prototype) также автоматически добавляется свойство constructor, указывающее обратно на функцию. Получается такая вот циклическая ссылка.

Теперь этот объект, который можно описать как {constructor: ...здесь ссылка на фунцию...} - и есть прототип функции.
*/

//Object - действительно, объект
alert(typeof make_me.prototype.constructor); //Function - это наша функция
alert(make_me.prototype.constructor === make_me); //true

//Добавляем в прототип функции make_me новый метод

Child=new make_me("Вася" ); //меня запустили
/* Теперь помимо всего того, что описано в предыдущем примере, дополнительно в объекте child создается скрытое свойство [], которое указывает на тот же объект, что и make_me.prototype. Т.к. свойство скрыто, мы не можем ни просмотреть его значение, ни изменить его - однако оно играет важную роль в дальнейшей работе */

Alert(child.name); //Вася
child.show_name(); //Вася

Child.set_name("Коля" );
/* Сначала, интерпретатор ищет метод set_name в объекте child. Так как его там нет, он продолжает поиск в свойстве child.[], находит его там и запускает. */
child.show_name(); //Коля - теперь Васю зовут Коля:)

Make_me.prototype.show_name2=function () {alert("Привет, " + this .name;} //Т.к. прототип - это обычный объект, мы точно также можем его менять на лету

Child2=new make_me("Петя" );
child2.show_name2(); //Привет, Петя
child.show_name2(); //Привет, Коля - изменения в прототипе влияют не только на вновь созданные объекты, но и на все старые

Child2.show_name2=function () {alert("Не буду говорить свое имя" );} //Мы по прежнему можем изменить сам объект, при этом новый метод show_name2 в данном объекте (и только в нем) как бы "затрет" старый метод из прототипа
child2.show_name2(); //Не буду говорить свое имя - т.к. у нас теперь есть собственный метод show_name2, то он и вызывается, и поиск в прототипе не происходит

Child.show_name2(); //Привет, Коля - здесь все по прежнему

Make_me.prototype={prop: "hello" } //Попробуем пересоздать прототип заново

Alert(child.prop); //undefined
child.show_name2(); //Привет, Коля
/* Если вспомнить, что такое работа по ссылке, то все понятно. Пересоздание прототипа рвет связь, и теперь свойство [] у объектов child и child2 указывают на один объект (который раньше был прототипом функции make_me), а свойство make_me.prototype - на другой объект, который является новым прототипом функции make_me */

Child3=new make_me("Олег" );
alert(child3.prop); //hello - что и следовало ожидать


* This source code was highlighted with Source Code Highlighter .

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

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

make_me=function (_name) {
alert("меня запустили" );
this .name=_name;
this .show_name=function () {alert(this .name);}
}

Make_me.prototype.set_name=function (_name) {this .name=_name;}
child=new make_me("Вася" );

Alert(typeof make_me.prototype); //object - у функции есть свойство prototype
alert(typeof child.prototype); //undefined - у созданного объекта НЕТ свойства prototype
alert(child.constructor.prototype === make_me.prototype); //true - зато у объекта есть свойство constructor, которое указывает на функцию-конструктор make_me, у которой, в свою очередь, есть свойство prototype


* This source code was highlighted with Source Code Highlighter .

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

Необходимо всегда четко понимать, что если речь идет о прототипе конструктора - то это всегда свойство prototype, а если о прототипе созданного объекта - то это скрытое свойство [].

Наследование

Теперь мы знаем, что у каждого объекта есть скрытая ссылка на прототип, а каждый прототип - это обычный объект.
Наиболее чуткие читатели уже уловили запах рекурсии:)
Действительно, т.к. прототип - это обычный объект, то и он в свою очередь имеет ссылку на свой прототип, и так далее. Таким образом реализуется иерархия прототипов.
bird=function () {} //Это конструктор птички
bird.prototype.cry=function (){alert("Кри!" );} //Птичка умеет кричать
bird.prototype.fly=function (){alert("Я лечу!" );} //и летать

Duck=function () {}
duck.prototype=new bird();
duck.prototype.cry=function (){alert("Кря-кря!" );} //Утка кричит по другому
duck.prototype.constructor=duck; //Принудительно устанавливаем свойство prototype.constructor в duck, т.к. иначе оно будет ссылаться на bird

Billy = new duck(); //Билли - это наша утка
billy.fly(); //Я лечу! - Билли может летать, потому что он птица
billy.cry(); //Кря-кря! - Билли кричит кря-кря, потому что он утка


* This source code was highlighted with Source Code Highlighter .

Так можно реализовывать иерархию любого уровня вложенности.

Задача на звездочку

Теперь, раз уж мы столько знаем обо всем этом, давайте попробуем разобраться, сколько всего происходит в этих трех строчках
make_me=function () {}
child=new make_me();
alert(child.toString()); //выводит

* This source code was highlighted with Source Code Highlighter .

В первой строке мы создаем новую функцию и переменную make_me, которая указывает на эту функцию. При этом создается прототип функции, make_me.prototype, в котором содержится свойство constructor, указывающее на make_me.
Но это далеко не все:)
Т.к. функция make_me - это тоже объект, то он в свою очередь имеет папу и маму, т.е. конструктор и прототип. Его конструктор - это родная функция языка Function(), а прототип - объект, содержащий в себе методы call, apply и т.д. - именно благодаря этому прототипу мы и можем пользоваться этими методами в любой функции. Таким образом, у функции make_me появляется свойство [], указывающее на Function.prototype.

В свою очередь, прототип конструктора Function - тоже объект, конструктором которого является (сюрприз!) Object (т.е. Function.prototype.[].constructor===Object), а прототипом - объект, содержащий стандартные свойства и методы объекта, такие как toString, hasOwnProperty и другие (другими словами - Function.prototype.[]["hasOwnProperty"] - это как раз тот самый метод, которым мы можем пользоваться во всех производных объектах - причем это именно собственной метод данного объекта, а не наследованный). Вот таким вот интересным образом мы обнаруживаем, что все виды объектов являются производными от Object.

Можем ли мы продолжить дальше? Оказывается, нет. Object.prototype именно потому и содержит базовые свойства объекта, что не имеет собственного прототипа. Object.prototype.[]=null; В этом месте путешествие по цепочке прототипов в поиске свойства или метода прекращается.

Еще один интересный факт - конструктором Object является Function. Т.е. Object.[].constructor===Function.
Налицо еще одна циклическая ссылка - конструктор Object это Function, а конструктор Function.prototype - это Object.

Вернемся к нашему примеру. Как создается функция мы уже поняли, теперь перейдем ко второй строке. Там мы создаем объект child, конструктором которого является функция make_me, а прототипом - make_me.prototype.

Ну и в третей строчке мы видим, как интепретатор поднимается по цепочке, от child к child.[] (он же make_me.prototype), затем к child.[].[] (он же Object.prototype), и уже там находит метод toString, который и запускает на выполнение.

Примеси

Может показаться, что наследование через прототипы - единственный способ, возможный в JavaScript. Это не так.
Мы имеем дело с очень гибким языком, который предоставляет не столько правила, сколько возможности.

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

//Это конструктор человека
man=function () {
this .live=function (){alert("Я живу" );} //Человек умеет жить
this .walk=function (){alert("Я иду" );} //Человек умеет ходить
}

//Это конструктор поэта
poet=function (){
this .kill=function (){alert("Поэт убил человека" );} //Поэт может убить человека
this .live=function (){alert("Я мертв" );} //От этого человек умрет
}

Vladimir=new man(); //Владимир - человек
vladimir.live(); //Я живу - он жив
vladimir.walk(); //Я иду - он ходит

Poet.call(vladimir); //Выполняем конструктор poet для объекта vladimir
vladimir.kill(); //Поэт убил человека
vladimir.live(); //Я мертв

//А теперь фокус
man.call(vladimir);
vladimir.live(); //Я живу


* This source code was highlighted with Source Code Highlighter .

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

Upd: Замыкания и приватные свойства

Чтобы не раздувать эту и без того немаленькую статью, даю ссылку на пост Замыкания в JavaScript , где про это довольно подробно написано.

Что теперь со всем этим делать

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

Причем вопрос о цене довольно нетривиален, особенно если мы говорим о разработке под браузер Internet Explorer 6 и 7 версий.
1. Память - тут все просто. Во всех браузерах наследование на прототипах отнимает в разы меньше памяти, чем при создании методов через конструкторы. Причем, чем больше методов и свойств у нас есть, тем больше разница. Однако, стоит помнить, что если у нас не тысяча одинаковых объектов а всего лишь один, то расходы памяти в любом случае будут небольшими, т.к. здесь стоит учитывать другие факторы.
2. Процессорное время - здесь основные тонкости связанны именно с браузерами от Microsoft.
С одной стороны, объекты, где методы и свойства создаются через конструктор - могут создаваться в разы (в некоторых случаях в десятки и сотни раз) медленнее, чем через прототип. Чем больше методов - тем медленнее. Так что если у вас в IE замирает на несколько секунд во время инициализации скрипта - есть повод копать в эту сторону.

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

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

P.S. Обычно в статьях подобного рода автор предлагает некую обертку, либо пытающуюся реализовать класс-объектное наследование на базе прототипного, либо просто синтаксический сахар для прототипного наследования. Я не делаю этого намеренно, т.к. считаю, что человек, понявший смысл данной статьи, способен сам для себя написать любую обертку, и еще много интересных вещей:)

Теги: Добавить метки

JavaScript is designed on a simple object-based paradigm. An object is a collection of properties, and a property is an association between a name (or key ) and a value. A property"s value can be a function, in which case the property is known as a method. In addition to objects that are predefined in the browser, you can define your own objects. This chapter describes how to use objects, properties, functions, and methods, and how to create your own objects.

Objects overview

Objects in JavaScript, just as in many other programming languages, can be compared to objects in real life. The concept of objects in JavaScript can be understood with real life, tangible objects.

In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties. A cup has a color, a design, weight, a material it is made of, etc. The same way, JavaScript objects can have properties, which define their characteristics.

Objects and properties

A JavaScript object has properties associated with it. A property of an object can be explained as a variable that is attached to the object. Object properties are basically the same as ordinary JavaScript variables, except for the attachment to objects. The properties of an object define the characteristics of the object. You access the properties of an object with a simple dot-notation:

ObjectName.propertyName

Like all JavaScript variables, both the object name (which could be a normal variable) and property name are case sensitive. You can define a property by assigning it a value. For example, let"s create an object named myCar and give it properties named make , model , and year as follows:

Var myCar = new Object(); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969; myCar.color; // undefined

Properties of JavaScript objects can also be accessed or set using a bracket notation (for more details see property accessors). Objects are sometimes called associative arrays , since each property is associated with a string value that can be used to access it. So, for example, you could access the properties of the myCar object as follows:

MyCar["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["year"] = 1969;

An object property name can be any valid JavaScript string, or anything that can be converted to a string, including the empty string. However, any property name that is not a valid JavaScript identifier (for example, a property name that has a space or a hyphen, or that starts with a number) can only be accessed using the square bracket notation. This notation is also very useful when property names are to be dynamically determined (when the property name is not determined until runtime). Examples are as follows:

// four variables are created and assigned in a single go, // separated by commas var myObj = new Object(), str = "myString", rand = Math.random(), obj = new Object(); myObj.type = "Dot syntax"; myObj["date created"] = "String with space"; myObj = "String value"; myObj = "Random Number"; myObj = "Object"; myObj[""] = "Even an empty string"; console.log(myObj);

Please note that all keys in the square bracket notation are converted to string unless they"re Symbols, since JavaScript object property names (keys) can only be strings or Symbols (at some point, private names will also be added as the class fields proposal progresses, but you won"t use them with form). For example, in the above code, when the key obj is added to the myObj , JavaScript will call the obj.toString() method, and use this result string as the new key.

You can also access properties by using a string value that is stored in a variable:

Var propertyName = "make"; myCar = "Ford"; propertyName = "model"; myCar = "Mustang";

Using a constructor function

Alternatively, you can create an object with these two steps:

  1. Define the object type by writing a constructor function. There is a strong convention, with good reason, to use a capital initial letter.
  2. Create an instance of the object with new .

To define an object type, create a function for the object type that specifies its name, properties, and methods. For example, suppose you want to create an object type for cars. You want this type of object to be called Car , and you want it to have properties for make, model, and year. To do this, you would write the following function:

Function Car(make, model, year) { this.make = make; this.model = model; this.year = year; }

Notice the use of this to assign values to the object"s properties based on the values passed to the function.

Now you can create an object called mycar as follows:

Var mycar = new Car("Eagle", "Talon TSi", 1993);

This statement creates mycar and assigns it the specified values for its properties. Then the value of mycar.make is the string "Eagle", mycar.year is the integer 1993, and so on.

You can create any number of Car objects by calls to new . For example,

Var kenscar = new Car("Nissan", "300ZX", 1992); var vpgscar = new Car("Mazda", "Miata", 1990);

An object can have a property that is itself another object. For example, suppose you define an object called person as follows:

Function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; }

and then instantiate two new person objects as follows:

Var rand = new Person("Rand McKinnon", 33, "M"); var ken = new Person("Ken Jones", 39, "M");

Then, you can rewrite the definition of Car to include an owner property that takes a person object, as follows:

Function Car(make, model, year, owner) { this.make = make; this.model = model; this.year = year; this.owner = owner; }

To instantiate the new objects, you then use the following:

Var car1 = new Car("Eagle", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);

Notice that instead of passing a literal string or integer value when creating the new objects, the above statements pass the objects rand and ken as the arguments for the owners. Then if you want to find out the name of the owner of car2, you can access the following property:

Car2.owner.name

Note that you can always add a property to a previously defined object. For example, the statement

Car1.color = "black";

adds a property color to car1, and assigns it a value of "black." However, this does not affect any other objects. To add the new property to all objects of the same type, you have to add the property to the definition of the Car object type.

Using the Object.create method

See also

  • To dive deeper, read about the details of javaScript"s objects model .
  • To learn about ECMAScript 2015 classes (a new way to create objects), read the JavaScript classes chapter.

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

Обзор объектов

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

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

Объекты и свойства

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

ObjectName.propertyName

Как и все переменные JavaScript, имя объекта (которое тоже может быть переменной) и имя свойства являются чуствительными к регистру. Вы можете определить свойство указав его значение. Например, давайте создадим объект myCar и определим его свойства make , model , и year следующим образом:

Var myCar = new Object(); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969;

Неопределенные свойства объекта являются undefined (а не null).

MyCar. color; // undefined

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

MyCar["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["year"] = 1969;

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

Var myObj = new Object(), str = "myString", rand = Math.random(), obj = new Object(); myObj.type = "Dot syntax"; myObj["date created"] = "String with space"; myObj = "String value"; myObj = "Random Number"; myObj = "Object"; myObj[""] = "Even an empty string"; console.log(myObj);

Обратите внимание, что все ключи с квадратными скобками преобразуются в тип String, поскольку объекты в JavaScript могут иметь в качестве ключа только тип String. Например, в приведенном выше коде, когда ключ obj добавляется в myObj , JavaScript вызывает метод obj.toString () и использует эту результирующую строку в качестве нового ключа.

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

Var propertyName = "make"; myCar = "Ford"; propertyName = "model"; myCar = "Mustang";

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

Function showProps(obj, objName) { var result = ""; for (var i in obj) { if (obj.hasOwnProperty(i)) { result += objName + "." + i + " = " + obj[i] + "\n"; } } return result; }

Так что если вызвать эту функцию вот так showProps(myCar, "myCar"), то получим результат:

MyCar.make = Ford myCar.model = Mustang myCar.year = 1969

Перечисление всех свойств объекта

Использование функции конструктора

Другой способ создать объект в два шага описан ниже:

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

Чтобы определить тип объекта создайте функцию, которая определяет тип объекта, его имя, свойства и методы. Например предположим, что вы хотите создать тип объекта для описания машин. Вы хотите, чтобы объект этого типа назывался car , и вы хотите, чтобы у него были свойства make, model, и year. Чтобы сделать это, напишите следующую функцию:

Function Car(make, model, year) { this.make = make; this.model = model; this.year = year; }

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

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

Var mycar = new Car("Eagle", "Talon TSi", 1993);

Эта инструкция создает объект типа Car с ссылкой mycar и присваивает определенные значения его свойствам. Значением mycar.make станет строка "Eagle", mycar.year - это целое число 1993, и так далее.

Вы можете создать столько объектов car, сколько нужно, просто вызывая new . Например:

Var kenscar = new Car("Nissan", "300ZX", 1992); var vpgscar = new Car("Mazda", "Miata", 1990);

Объект может иметь свойство, которое будет другим объектом. Например, далее определяется объект типа Person следующим образом:

Function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; }

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

Var rand = new Person("Rand McKinnon", 33, "M"); var ken = new Person("Ken Jones", 39, "M");

Затем, вы можете переписать определение car и включить в него свойство owner , которому назначить объект person следующим образом:

Function Car(make, model, year, owner) { this.make = make; this.model = model; this.year = year; this.owner = owner; }

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

Var car1 = new Car("Eagle", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);

Заметьте, что вместо того, чтобы передавать строку, литерал или целое число при создании новых объектов, в выражениях выше передаются объекты rand и ken как аргумент функции. Теперь, если вам нужно узнать имя владельца car2, это можно сделать следующим образом:

Car2.owner

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

Car1.color = "black";

добавляет свойство color к car1, и устанавливаего его значение равным "black." Как бы там ни было, это не влияет на любые другие объекты. Чтобы добавить новое свойство всем объектам одного типа, вы должны добавить свойство в определение типа объекта car .

Использование метода Object.create

Объекты также можно создавать с помощью метода Object.create . Этот метод очень удобен, так как позволяет вам указывать объект прототип для нового вашего объекта без определения функции конструктора.

// список свойств и методов для Animal var Animal = { type: "Invertebrates", // Значение type по умолчанию displayType: function() { // Метод отображающий тип объекта Animal console.log(this.type); } }; // Создаем объект Animal var animal1 = Object.create(Animal); animal1.displayType(); // Выведет:Invertebrates // Создаем объект Animal и присваиваем ему type = Fishes var fish = Object.create(Animal); fish.type = "Fishes"; fish.displayType(); // Выведет:Fishes

Наследование

Все объекты в JavaScript наследуются как минимум от другого объекта. Объект, от которого произошло наследование называется прототипом, и унаследованные свойства могут быть найдены в объекте prototype конструктора.

Индексы свойств объекта

В JavaScript 1.0 вы можете сослаться на свойства объекта либо по его имени, либо по его порядковому индексу. В JavaScript 1.1 и позже, если вы изначально определили свойство по имени, вы всегда должны ссылаться на него по его имени, и если вы изначально определили свойство по индексу, то должны ссылаться на него по его индексу.

Это ограничение налагается когда вы создаете объект и его свойства с помощью функции конструктора (как мы это делали ранее с типом Car ) и когда вы определяете индивидуальные свойства явно (например, myCar.color = "red"). Если вы изначально определили свойство объекта через индекс, например myCar = "25 mpg" , то впоследствии сослаться на это свойство можно только так myCar .

Исключение из правил - объекты, отображаемые из HTML, например массив forms . Вы всегда можете сослаться на объекты в этих массивах или используя их индекс (который основывается на порядке появления в HTML документе), или по их именам (если таковые были определены). Например, если второй html-тег

в документе имеет значение аттрибута NAME равное "myForm", вы можете сослаться на эту форму вот так: document.forms или document.forms["myForm"] или document.myForm .

Определение свойств для типа объекта

Вы можете добавить свойство к ранее определенному типу объекта воспользовавшись специальным свойством prototype . Через prototype создается свойство, единое для всех объектов данного типа, а не одного экземпляра этого типа объекта. Следующий код демонстрирует это, добавляя свойство color ко всем объектам типа car , а затем присваивая значение свойству color объекта car1 .

Car.prototype.color = null; car1.color = "black";

В коде ниже показано, как с помощью геттера и сеттера можно расширить прототип объекта Date и добавить ему свойство year, которое будет работать у всех экземпляров класса Date . Этот код использует существующие методы класса Date - getFullYear и setFullYear для работы геттера и сеттера.

Определение геттера и сеттера для свойства year:

Var d = Date.prototype; Object.defineProperty(d, "year", { get: function() { return this.getFullYear(); }, set: function(y) { this.setFullYear(y); } });

Использование свойства year заданного геттером и сеттером:

Var now = new Date(); console.log(now.year); // 2000 now.year = 2001; // 987617605170 console.log(now); // Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001

В принципе, геттеры и сеттеры могут быть либо:

Когда определение геттера и сеттера использует , все что вам нужно, это дополнить геттер префиксом get а сеттер префиксом set . При этом, метод геттера не должен ожидать каких либо параметров, в то время как метод сеттера принимает один единственный параметр (новое значение для присвоения свойству). Например:

Var o = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2; } };

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

Var o = { a: 0 }; Object.defineProperties(o, { "b": { get: function() { return this.a + 1; } }, "c": { set: function(x) { this.a = x / 2; } } }); o.c = 10; // Запускает сеттер, который присваивает 10 / 2 (5) свойству "a" console.log(o.b); // Запускает геттер, который возвращает a + 1 (тоесть 6)

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

Удаление свойств

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

//Creates a new object, myobj, with two properties, a and b. var myobj = new Object; myobj.a = 5; myobj.b = 12; //Removes the a property, leaving myobj with only the b property. delete myobj.a;

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

G = 17; delete g;