Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Понимание ООП в JavaScript (https://javascript.ru/forum/misc/3070-ponimanie-oop-v-javascript.html)

kefi 16.03.2009 22:21

Цитата:

Сообщение от Gvozd
вы имеете в виду a.constructor?

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

Gvozd 16.03.2009 22:28

Цитата:

Сообщение от kefi
отчего это свойство prototype недоступно для объекта, не являющегося конструктором ?

запомните очень важную вещь:
Прототип и свойство prototype это разные вещи и понятия

свойство prototype конструктора указывает какой прототип будет у объектов созданных при помощи этого конструктора
прототип(доступный в мозилле в виде свойства объекта __proto__.в других браузерах прототип вообще напрямую недоступен) определяет откуда надо брать какое-то свойство, если в объекте оно не определено

таким образом свойство prototype используется только объектами-
конструкторами.

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

kefi 16.03.2009 23:56

Цитата:

Сообщение от Gvozd (Сообщение 14464)
запомните очень важную вещь:
Прототип и свойство prototype это разные вещи и понятия

Пожалуй, я это давно понял, а причина этой непонятки была в том, что я не мог уложить в голове другую важную вещь, - а именно то, что свойство prototype имеется не у родителя объекта, а у его конструктора , и ,как и остальные свойства встроенных объектов-конструкторов не наследуется (за исключением ниже приведенного случая ).
Т.е. , все встроенные объекты Object,Array,Function etc являются объектами-конструкторами и не являются предками (прототипами) объектов-НЕконструкторов, ( впрочем, видимо, если они не будут специально подставлены в свойство prototype конструкторов объектов-НЕконструкторов :
var Constr=new Function(); Constr.prototype=Object ; var a=new Constr() ;
alert(a.prototype!==undefined) // TRUE )

Интересно также всвязи со сказанным посмотреть иерархию объектов-конструкторов типа Array,Funciton, etc .

Да, по поводу объяснения выше ,
Цитата:

Сообщение от Gvozd
// - значением свойства prototype объекта-конструктора становится вновь созданный объект - А что это за объект ??- непонятно.
до тех пор, пока вы не переопределите свойство prototype объекта-конструктора, это просто пустой объект типа constr (то есть его конуструктором считается функция constr), с пустым набором свойств

Видимо, все-таки - это пустой объект не типа constr, а типа Object .

Gvozd 17.03.2009 01:04

Цитата:

Сообщение от kefi
Видимо, все-таки - это пустой объект не типа constr, а типа Object .

глянул Ecma
по ходу да.

какие-то еще вопосы?

kefi 17.03.2009 01:27

Цитата:

Сообщение от Gvozd
какие-то еще вопросы?

Ну, а как же.
Самый простой - хотелось бы понять, как отличать объекты-конструкторы от объектов-НЕконструкторов ?
- И как присваивать и смотреть аттрибуты ( ReadOnly etc ) свойств объектов ?
- И почему в документации гворитсяЮ что свйоства prototype встроенных объектов нельзя переопределять , когда запросто проходит, например Object.prototype=Array; ?

ЗЫ. Я так понимаю, что в предыдущем моем посте все сказано верно ? По поводу иерархии объектов-конструкторов еще сам додумаю. Тогда уж ,если, выскажусь.

Gvozd 17.03.2009 01:52

Цитата:

Сообщение от kefi
как отличать объекты-конструкторы от объектов-НЕконструкторов.

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

Цитата:

Сообщение от kefi
И как присваивать и смотреть аттрибуты ( ReadOnly etc ) свойств объектов ?

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

Цитата:

Сообщение от kefi
ЗЫ. Я так понимаю, что в предыдущем моем посте все сказано верно ? По поводу иерархии объектов-конструкторов еще сам додумаю. Тогда уж ,если, выскажусь.

вроде да.ошибок не вижу.
но башка сегодня уже не варит.

PS у вас начинаются вопросы на совсем глубокое знание стандарта Ecma.а я его краем глаза проглядывал.
в дальнейший путь я буду уже идти скорее вровень с вами, чем помогать вам.
а учитывая, что JS не является моим основным профилем работы, мне пока не удастся уделить достаточно времени и желания изучению стандарта и помощи вам
что смогу подскажу.но уже не так активно.
короче, читайте стандарт языка, и пытайтесь понять сами.думаю дальше разбиратся на основе сухой документации у вас получится

kefi 18.03.2009 22:02

Отчего так для Opera и IE ?:
with (Function.prototype) alert([ 
// Следующие три свойства дают FALSE - в MS JS (IE) и Opera :
 hasOwnProperty("prototype"),   // Function.prototype.prototype==null, в потомках объектах-конструкторах Constr это свойство переопределяется на своего спутника <c>
 hasOwnProperty("arguments"),   //
 hasOwnProperty("caller"),      //  
])

Откуда же берутся ( или чьими собственными свойствами ) являются arguments,caller ? Про prototype то же, но оно у этого объекта как-то вообще непонятно - зачем .

twolf 20.03.2009 12:49

"вкурил" что называется тему. Потом решил почитать что про это пишется у Флэнагана. у Zeroglif'a (по той ссылке) получилось лучше, гораздо подробнее и легче для восприятия.

Gvozd 20.03.2009 16:06

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

Zeroglif 20.03.2009 16:15

Цитата:

Сообщение от kefi
Отчего так для Opera и IE ?

Потому что "дополнительные мульки" (не-стандарт) в каждом движке реализованы по-своему (если вообще реализованы). Это что касается 'caller' и 'arguments'. В отношении собственного свойства 'prototype' у функции (Function.prototype) - это разночтение стандарта со стороны разработчиков.

kefi 20.03.2009 20:56

Цитата:

Сообщение от Zeroglif
Потому что "дополнительные мульки" (не-стандарт)

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

Zeroglif 20.03.2009 21:12

Цитата:

Сообщение от kefi
где ее взять

http://www.ecma-international.org/pu...s/Ecma-262.htm
Или на этом сайте есть переведённый вариант этого же документа (если нравится читать по-русски).
Цитата:

Сообщение от kefi
совместимы ли спецификации снизу вверх ?

Стараются.

kefi 20.03.2009 22:54

Насчет версий не понял, но
Вот еще вопросик :
известно, что Function.prototype.constructor указывает на Function,
Но кто считается действительным конструктором объекта-экземпляра Function ?
То, что Function создал самого себя сам как-то не укладывается в голове.

Zeroglif 21.03.2009 16:51

Цитата:

Сообщение от kefi
Известно, что Function.prototype.constructor указывает на Function. Но кто считается действительным конструктором объекта-экземпляра Function ? То, что Function создал самого себя сам как-то не укладывается в голове.

'Function' - это встроенный объект, тот, который "available whenever an ECMAScript program begins execution", его "действительный конструктор" остался в тени, за рамками стандарта.

'Function.prototype' - это другой встроенный объект с аналогично неизвестной историей конструирования. Для нас важны не встроенные (с ними и так всё понятно), а новые функции, появляющиеся в программе через 'new Function', для них и предусмотрено наследуемое свойство 'constructor', которое является родным свойством функции 'Function.prototype', но работает прежде всего для связи вновь созданных функций со своим "действительным конструктором", с 'Function'...

Dmitry A. Soshnikov 21.03.2009 20:10

Цитата:

Сообщение от kefi
То, что Function создал самого себя сам как-то не укладывается в голове.

Движок его создал и записал в поле constructor ссылку на созданный объект.

kefi 28.03.2009 18:32

Вот еще обнаружился непонятный интересный факт :
Если имеем
function X(){this.fld=123;} ; X.prototype.fld=1234;
x = new X() ;
То: x.fld!=X.prototype.fld , x==123
Т.е. как же так получается для x : поле fld берется не из прототипа x , а из нутренностей его конструктора ? Где же логика делегирования свойств прототипа его потомку ?

PS. С методами та же петрушка.

Gvozd 28.03.2009 18:50

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

kefi 28.03.2009 18:57

2 Gvozd >
Да, действительно , уже понял. Несколько увлекся ...

kefi 28.03.2009 19:14

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

Gvozd 28.03.2009 19:40

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

kefi 01.04.2009 09:56

Вот такой вопрос :

Вообще какие this поля и методы разумно держать в Конструкторе объекта ?

Zeroglif 01.04.2009 11:08

Любые, если они нужны лично "экземплярам".

kefi 02.04.2009 22:14

Вот такой вопрос :
А клонировать конструктор и связанный с ним прототип возможно ? И как ?

Zeroglif 03.04.2009 11:40

Клонировать deep? Функции не клонировать, объекты тяжело, т.к. нужно тип выяснять и т.д.

kefi 03.04.2009 19:51

Цитата:

Сообщение от Zeroglif
Клонировать deep?

Полностью.
Функции вроде как раз можно:
function f(a,b,c){/*код*/};
var f2=new Function(ВыделитьАрг(f,Первый),ВыделитьАрг(f,Второй),ВыделитьАрг(f,Последний),Выделить_код_тела(f))

правда не знаю , как передавать выделенные аргументы в Function , т.е. как составить выражение
new Function(от заранее неизвестного числа аргументов) ...

Dmitry A. Soshnikov 03.04.2009 20:28

Цитата:

Сообщение от kefi
new Function(

Всё равно не клон будет; функции, созданные таким способом, в качестве [[scope]] имеют глобальный объект.

Можно просто создавать новую ссылку на тот же блок кода. Правда, изменение свойств будет общее.

kefi 03.04.2009 22:07

Цитата:

Сообщение от Dmitry A. Soshnikov
Можно просто создавать новую ссылку на тот же блок кода

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

Dmitry A. Soshnikov 03.04.2009 23:15

kefi, ну, а неправильный [[scope]] - совсем неверно.

kefi 03.04.2009 23:42

Есть такой вопрос :
Свойства прототипа - это обычно неизменные , постоянные величины, определяемые только изначально проинициализированными значениями ?
Или в javascript широко используется их изменение во время работы программы ?

Dmitry A. Soshnikov 03.04.2009 23:49

Цитата:

Сообщение от kefi
Или в javascript широко используется их изменение во время работы программы ?

Да, используется (как и в любом динамическом языке). Так работают всякого рода плагины и т.д.

kefi 04.04.2009 01:14

2 Dmitry A. Soshnikov>
Просто, тогда получается, что производимые на основе такого прототипа потомки будут после каждого изменения прототипа разными, что в корне отлично от статического ООП , который при одних и тех же входных параметрах конструктора по операции new создает ничем не отличимые кроме адреса-ссылки экземпляры-клоны.
Мне казалось , что здесь тоже должна быть какая-то устойчивость прототипа, т.е. изменение его свойств в течение работы программы мне казалось , хоть язык и динамический, чем-то особенным , т.к. в противном случае скорее всего создаваемые программой на основе изменяемого прототипа экземпляры не должны обладать массовостью - "язык генерирует штучную продукцию" ...

Dmitry A. Soshnikov 04.04.2009 01:42

Цитата:

Сообщение от kefi
что в корне отлично от статического ООП

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

К примеру, в Ruby on Rails (web-фрейморк на Ruby) при создании модели таблицы БД, у объекта-модели появляются (наряду с основным методом .find()) в рантайме методы find_by_имя_колонки: например, find_by_name, find_by_surename и т.д. - динамически расширяется класс модели методами, чьи имена построены по именам колонок в таблице.

Все js-фреймворки, которые добавляют всякие методы в прототипы HTMLElement'a и т.д. (например $('#some-id').show() - и все инстансы HTMLElement "чудесным образом" имеют метод .show).

P.S.: динамическое изменение кода называется на жаргоне "Monkey Patch"

kefi 04.04.2009 13:46

Цитата:

Сообщение от Dmitry A. Soshnikov
при создании модели таблицы БД, у объекта-модели появляются (наряду с основным методом .find()) в рантайме методы find_by_имя_колонки: например, find_by_name, find_by_surename и т.д. - динамически расширяется класс модели методами, чьи имена построены по именам колонок в таблице.

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

Dmitry A. Soshnikov 04.04.2009 14:26

Цитата:

Сообщение от kefi
Но, как при этом формируются тела методов для поиска в каждой колонке ?

А внутри тел - всё тот же стандартный find с нужным фильтром. Делается это больше для абстракции и человекообразности кода.

Цитата:

Сообщение от kefi
иначе в чем смысл создавать много методов для выполнения однотипных действий ?

Повышение абстракции. Методы (во всяком случае, в данной конкретной реализации - в ActiveRecord в Ruby on Rails) создаются "лениво", а не вся куча сразу для каждой колонки. При первом обращении к несуществующему методу (такие случаи отлавливаются специальным методом method_missing), он создаётся; дальнейшие вызовы уже не тратят на это время.

kefi 04.04.2009 16:38

Цитата:

Сообщение от Dmitry A. Soshnikov
Делается это больше для абстракции и человекообразности кода

Это самое непонятное. А как эта самая абстракция может использоваться далее, т.е. что она нам дает ( про человекообразность уже даже и не спрашиваю ) ?

Dmitry A. Soshnikov 04.04.2009 18:23

Цитата:

Сообщение от kefi
( про человекообразность уже даже и не спрашиваю ) ?

От чего же? Я вижу будущее программирования, как сведение написания кода вообще к минимуму и общение с машинами/роботами и т.д. на языках приближённых к человеческим. Но это отстранённая философия, конечно ;)

Цитата:

Сообщение от kefi
что она нам дает

Упрощение, очеловечение.

Но. Основным моментом, всё-таки, является не просто "косметические украшения" типа "find_by_что_то_там", а - динамические изменения с целью определения нужного функционала (возможно, определяемого по ситуации, - с одними входными параметрами объект будет иметь одни свойства и методы, с другими - другие). Т.е. это расширение/сужение объектов, согласно "меняющейся ситуации".

kefi 04.04.2009 19:19

Цитата:

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

Ну вот как-то этот пример не позволяет почувствовать настоящее изменение функционала. Фактически функционал остается всё тот же стандартный find с нужным фильтром. Вот если бы как-то менялся сам метод, динамически модифицируя свой код, в зависимости от условий внешней среды, тогда было бы понятнее целесообразность ...

Цитата:

Сообщение от Dmitry A. Soshnikov
сведение написания кода вообще к минимуму и общение с машинами/роботами и т.д. на языках приближённых к человеческим. Но это отстранённая философия, конечно

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

Dmitry A. Soshnikov 04.04.2009 23:44

Цитата:

Сообщение от kefi
Вот если бы как-то менялся сам метод, динамически модифицируя свой код, в зависимости от условий внешней среды, тогда было бы понятнее целесообразность ...

Как правило, меняются не тела методов (хотя, никто этого не исключает), а объекты при мутировании обрастают новым функционалом. Написали Вы объект, рассказали о нём. Дальше десять других программистов написали плагины (Monkey Patch'и) к Вашему объекту - при подключении этих плагинов, объект приобретает/видоизменяет необходимый функционал.

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

Zeroglif 05.04.2009 13:28

Цитата:

Сообщение от kefi
что производимые на основе такого прототипа потомки будут после каждого изменения прототипа разными

Если сам объект-прототип не менялся (на другой), то объекты-экземпляры "видят" его одинаково, главное, чтобы вновь добавленное свойство существовало в момент обращения к нему.

kefi 05.04.2009 15:15

Цитата:

Сообщение от Dmitry A. Soshnikov
(а) на этапе проектирования (когда подключаются плагины),

Но практически это ничем не отличается от статического ООП программироания в Java. Там так же точно , например, один написал систему в которой определены интерфейсы (или абстрактные классы) общения с объектами этой системы , после чего другие пишут развитие этой системы , реализуя эти интерфейсы. Т.е. это все стадия проектирования, где осуществляется не динамическое , а статическое программирование. Отличие от java в этом случае будет только в гибкости - в javascript можно :
- добавлять новые методы, удалять старые ( причем, в отличие от java, уже реализованные ) ;
- добавленная программма плагина может переопределить методы уже созданных инстанций, если вызывается после их создания.
Но это все , как я вижу, не есть действительно динамические качества программы , которые должны были бы проявляться как изменение тел свойств объектов, построение новых конструкторов со своими методами программой, которая УЖЕ спроектирована , а ее гибкость.

Цитата:

Сообщение от Dmitry A. Soshnikov
(б) - в рантайме, по изменяющимся условиям (например, имена колонок таблиц).

А это действительно будет динамикой , т.е. уже существующая программа умеет создавать новые свойства своим объектам.Но опять же здесь, если я правильно смог понять, это не так целесообразно делать по сравнению со статическим ООП java, т.е. это скорее получается удобная гибкая особенность(фича) языка. Т.е. внешним модулям можно разговаривать с таким объектом свойства которого подстраиваются в зависимости от их требований так :
find_by_name,  find_by_surename ,  find_by_любимое _блюдо  ...

а статическая ООП программа тоже самое будет делать так :
find_by("name"),  find_by("surename"),  find_by("любимое _блюдо")  ...

Не очень в этом случае понятно в чем будет преимущество от динамичного(самостоятельн� �го развития программой своих объектов) кроме уже вышесказанного будут формироваться только слова общепонятного языка общения между компонентами системы . И даже еще программисту придется понимать этот дополнительный язык - вместо одного слова find_by с параметром появляются много слов .
Раз "как правило, меняются не тела методов (хотя, никто этого не исключает)", так если никто этого не исключает , то нельзя ли привести пример, когда действительно уже спроектированная программа строила новые конструкторы со своими методами , изменяла тела свойств объектов .

PS Поправьте меня, если я что не так понял и толковал .


Часовой пояс GMT +3, время: 00:21.