часть кода присвоенная свойству объекта это

JavaScript: Объекты

Объект – это неупорядоченная коллекция свойств. Свойство – это часть объекта имитирующая переменную. Свойство состоит из имени и значения.

В JavaScript есть три категории объектов:

Создание объекта

Объект можно создать с помощью литерала объекта или оператора new с конструктором.

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

Создание объекта с помощью оператора new:

Операции с объектом

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

Обращение к свойству и изменение значения осуществляется точно так же (с помощью операторов доступа):

Удаление свойства осуществляется с помощью оператора delete:

Для перебора свойств объекта используется цикл for-in:

Методы объекта

Вместо ключевого слова this можно использовать непосредственно имя объекта, но это не очень удобно, так как, если изменится имя объекта, в методах придётся также изменять имя:

Источник

Подробности о JavaScript-объектах

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

часть кода присвоенная свойству объекта это. Смотреть фото часть кода присвоенная свойству объекта это. Смотреть картинку часть кода присвоенная свойству объекта это. Картинка про часть кода присвоенная свойству объекта это. Фото часть кода присвоенная свойству объекта это

NB: Информацию из публикации на практике следует применять крайне аккуратно и под присмотром более опытных коллег.

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

Виды свойств объектов

▍Свойства, хранящие данные

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

Свойства name и id объекта obj называются свойствами, хранящими данные, или «свойствами с данными» (Data Properties). Это — привычные свойства, которые постоянно встречаются в JavaScript-коде. Какими ещё видами свойств могут обладать объекты?

▍Свойства с методами доступа

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

Вот как выглядит объявление объекта с геттером и сеттером:

Вот как это может выглядеть:

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

Зачем кому-то могут понадобиться свойства с методами доступа, если можно спокойно работать с обычными свойствами? Например, они могут понадобиться для того, чтобы записывать в журнал сведения об операциях чтения свойств, или для того, чтобы хранить историю изменений значений свойств. Свойства с методами доступа дают нам все возможности обработки данных с помощью функций и простоту, характерную для работы с обычными свойствами. Подробнее об использовании таких свойств можно почитать здесь.

Как JavaScript отличает обычные свойства, хранящие данные, от свойств с методами доступа? Выясним это.

Дескрипторы свойств объектов

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

▍Атрибуты свойств

Атрибуты используются для задания и описания состояния свойств объектов. Набор атрибутов свойства называется дескриптором. Существует шесть атрибутов свойств:

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

часть кода присвоенная свойству объекта это. Смотреть фото часть кода присвоенная свойству объекта это. Смотреть картинку часть кода присвоенная свойству объекта это. Картинка про часть кода присвоенная свойству объекта это. Фото часть кода присвоенная свойству объекта это

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

Надо отметить, что состав атрибутов конкретного свойства зависит от его вида. Все шесть атрибутов у одного и того же свойства не встречаются.

▍[[Value]]

Данный атрибут хранит ссылку на функцию, которая представляет собой свойство-геттер. Эта функция вызывается без аргументов при попытке чтения значения свойства.

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

В этом примере правая часть выражения передаётся в виде аргумента val функции-сеттеру. Вот код, в котором демонстрируется использование сеттеров и геттеров.

▍[[Writable]]

▍[[Enumerable]]

▍[[Configurable]]

Этот атрибут тоже представлен логическим значением. Вот что происходит в том случае, если в нём хранится значение false :

Работа с дескрипторами

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

▍Метод Object.getOwnPropertyDescriptor()

▍Метод Object.defineProperty()

Защита объектов

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

▍Метод Object.preventExtensions()

Метод Object.preventExtensions() предотвращает расширение объекта, то есть — добавление в него новых свойств. Он принимает объект и делает его нерасширяемым. Обратите внимание на то, что свойства из такого объекта можно удалять. Рассмотрим пример:

▍Метод Object.seal()

Метод seal() как бы «запечатывает» объекты. Вот о чём идёт речь:

▍Метод Object.freeze()

Метод freeze() позволяет «замораживать» объекты, оснащая их максимально возможным в JavaScript уровнем защиты. Вот как он работает:

▍Обзор методов, используемых для защиты объектов

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

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

Создание свойстваЧтение свойстваПерезапись свойстваУдаление свойства
Object.freeze()+
Object.seal()++
Object.preventExtensions()+++

Итоги

Учитывая то, как часто объекты используются в JavaScript-коде, каждому разработчику важно знать о том, как они устроены. Надеемся, то, что вы узнали, прочтя этот материал, вам пригодится. К тому же, теперь вы знаете ответы на вопросы, перечисленные в начале статьи.

Уважаемые читатели! Как вы защищает JavaScript-объекты?

Источник

Форум

Справочник

Объекты Javascript в примерах

В этой статье описаны базовые свойства объектов javascript, создание и изменение, перечисление свойств и т.п.

Объект в javascript представляет собой обычный ассоциативный массив или, иначе говоря, «хэш». Он хранит любые соответствия «ключ => значение» и имеет несколько стандартных методов.

Создание и работа со свойствами

Создание объекта

Следующие два варианта создания объекта эквивалентны:

Добавление свойств

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

Доступ к свойствам

Доступ к свойству осуществляется точно так же:

Если у объекта нет такого свойства, то результат будет ‘ undefined ‘

Никакой ошибки при обращении по несуществующему свойству не будет, просто вернется специальное значение undefined.

В javascript нельзя проверить существование глобальной переменной простым if :

Если x не определен, то конструкция if (x) вызовет ошибку javascript.

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

Удаляет свойство оператор delete:

Расширенное создание

Получившийся объект можно изобразить так:

часть кода присвоенная свойству объекта это. Смотреть фото часть кода присвоенная свойству объекта это. Смотреть картинку часть кода присвоенная свойству объекта это. Картинка про часть кода присвоенная свойству объекта это. Фото часть кода присвоенная свойству объекта это

Методы объектов

Добавление метода

Как и в других языках, у объектов javascript есть методы.

Например, создадим объект rabbit с методом run

Теперь можно запускать

Доступ к объекту из метода

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

Для этого используется ключевое слово this :

В отличие от многих языков, this никак не привязано к объекту, а обозначает просто объект, вызвавший функцию.

Более подробно о том, как работает this можно почитать в этой статье.

Перебор свойств объекта

Эта форма отфильтровывает свойства, которые принадлежат не самому объекту, а его прототипу. Поэтому она работает, даже если в прототип Object добавлены новые свойства.

Более элегантный вариант записи:

А почему ничего не сказано про прототипы (aka классы)?

// добавляем метод для прототипа
a.prototype.b = function () <
alert (‘test’);
>

// создаем объект
var a = new a();

Извиняюсь, сам дурак часть кода присвоенная свойству объекта это. Смотреть фото часть кода присвоенная свойству объекта это. Смотреть картинку часть кода присвоенная свойству объекта это. Картинка про часть кода присвоенная свойству объекта это. Фото часть кода присвоенная свойству объекта это

Хорошие статьи. Коротко, самое важное, без утаревших приемов, и всякой лабуды. Но я, собственно, по поводу Доступ к объекту из метода.
Раньше, было не нужно, а сейчас потребовалось, из повешанного на объект метода, получить ссылку не на объект его вызвавший, а на объект, на котором висит сам метод. Вроде вот он рядом :-), а как достать? Понимаю, что можно использовать прототип, но это нарушит всю задуманную задачу. Перекопал сегодня пол Интернета, но как то не смог ни чего найти. Такое чувство, что есть какая то простейшая возможность, но я её упустил.
Сам метод генерится динамически, и я, в принципе, могу жестко забить ссылку на объект, но это вроде не этично. 🙂

Что есть «объект, на котором висит сам метод»?

Что есть «объект, на котором висит сам метод»?

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

потом назначаем этот метод обработчиком события click.

Так «не принято», но мне нужно именно так.

И теперь, нужно из самого метода получить ссылку на DIV, на котором он висит.

В тему: в javascript, в отличие от C/Java/. методы НЕ висят на объектах. Контекст вызова метода целиком зависит от того, как его вызвали.

как можно исползоват функции php в javascript

РНР это серверные скрипты. JavaScript это клиентская часть. Можно вызвать через AJAX сам РНР скрипт и результат его работы получить через XML (или в HTML на худой конец). А дальше делай с этими данными все что нужно.

Думаю гораздо удобней будет получить результат ввиде JSON строки.

for sure! I agree. Thanks for these details. fence company cedar rapids

А можно ли изменит порядок свойств объекта? Можно ли с объектом работать как с массивом т.е. использовать теже методы предусмотренные для объект Array?

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

интересная статья. Много полезного узнал. Но вот интересно как можно вызывать метод объекта через setTimeout? Странно, вызов происходит, только метод не может получить доступ к свойствам объекта.

В примере ниже вызван метод объекта «metod» с правильным this

То есть, правильный указатель this передается через замыкание. Очень распространенный трюк.

Почему, когда я пытаюсь объявить объект Google maps в глобале,
ничего не происходит?

Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc. то почему я не могу перечислить его свойства путем :

И собственно сам вопрос :
Если Array является объектом (встроенным) со свойствами constructor,length,prototype,concat,join etc. то почему я получаю эти свойства у его прототипа, а не у него самого :

Еще пример для размышления :

Атрибут DontEnum не проверяется при прямом обращении, поэтому Array.prototype.join выдаст, что метод все-таки есть.

У класса Array есть свой, «статический», метод join:

И в чём принципиальная разница между a и b в следующем коде.

Я так понимаю ссылкой prototype (или [[prototype]]) и как следствие набором свойств и методов. Или ещё чем. И можно ли сказать, что b создается как и а, но после создания b вызывается ещё и MyFunc() (с this указывающем на b)

Как я полагаю, Вы сами ответили на свой вопрос. Мне кажется, что все именно так.

Very good post, thanks a lot.

Подскажите пожалуйста.
Есть такой когд (смотреть ниже), где нужно передать id в функцию clickFunction().
В результате получаю null. Пробовал ввести id напрямую, т. е. «list», браузер не выводит вообще ничего.

P.S.: заранее приношу ивинения, если пишу не туда.
Я «чайник» часть кода присвоенная свойству объекта это. Смотреть фото часть кода присвоенная свойству объекта это. Смотреть картинку часть кода присвоенная свойству объекта это. Картинка про часть кода присвоенная свойству объекта это. Фото часть кода присвоенная свойству объекта это

Источник

Работа с объектами в JavaScript: теория и практика

В этой статье я хочу по возможности полно и последовательно рассказать о том, что такое объект в 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, и что переменная test не является какой-то «главной» или «основной» ссылкой, а «test_link» — второстепенной.

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

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

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

alert(test.prop); //sometext
alert(test_link.prop); //sometext

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

//Добавляем новое свойство и удаляем старое
test.new_prop= ‘hello’ ;
delete test.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= //А вот и новый объект

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

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

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

obj= new String( ‘hello’ ); //Создаем строку как объект
simple= ‘hello’ ; //Создаем примитивное значение

obj.prop= ‘text’ ;
simple.prop= ‘text’ ;

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

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

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

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

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

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

Необходимо четко осознавать, 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[user]скрипт выдаст ошибку */

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

test.function_property.call(test2, ‘user_1’ ); //Good day, Петя.

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

Конструктор

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

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

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

child2= new make_me( ‘Петя’ );
child2.show_name(); //Петя

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

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

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

Прототип

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

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

make_me.prototype= //Попробуем пересоздать прототип заново

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

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

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

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

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

bird= function () <> //Это конструктор птички
bird.prototype.cry= function () //Птичка умеет кричать
bird.prototype.fly= function () //и летать

duck= function () <>
duck.prototype= new bird();
duck.prototype.cry= function () //Утка кричит по другому
duck.prototype.constructor=duck; //Принудительно устанавливаем свойство prototype.constructor в duck, т.к. иначе оно будет ссылаться на bird

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

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

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

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

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

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

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

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

Примеси

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

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

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

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

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

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

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

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

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

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

Источник

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

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