|
Модераторы: Sardar, Aliance |
|
Sardar |
|
|||
Бегун Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Предисловие.
Началось всё с этого топа. А что такое прототипы? Многие пытаються увидеть в JS обьектно ориентированный язык, но на самом деле это не так. JavaScript это обьектно протитипный язык програмирования, имеющий свои особенности мышления. Конечно можно за уши притянуть ООП подход к JS, но мы увидим что подобные громоздкие обороты лишни и к счастью не используються. Просто представь себе кучу классов, типов в JS, не динамичное поведение обьектов, жёстко прописанные интерфейсы и прочее... Впрочем почти всё, что здесь будет изложено, не используется, либо используется не явно, т.к. большинство народу просто не знают(догоняют) понятия динамически изменяемых и эффективных интерфейсов JS простой язык, идеально подходящий для манипулирования существующими обьектами. Такими обьектами могут быть элементы страницы, GUI(XUL) и т.п. Смысл этого текста научиться думать в обьектно прототипном стиле. Инфы много, я буду часто повторяться дабы вложить и закрепить инфу. Главы буду разбивать по постам. Любое утверждение будет подтверждаться примером. В этом топе запрещаеться писать отзывы и т.п. Создам для этого одтельный топ Там же можно направлять меня в те темы, которые не ясны, я их буду чётче/шире раскрывать. nJoy -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
Sardar |
|
|||
Бегун Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Начнём с основ, постепенно углублясь в детали.
Всё есть обьекты. В JS всё есть обьекты. Примитивные типы тоже существуют, для улучшения производительности и не только, но они при случае конвертируются в обьекты. Узнать тип переменной можно ключевым словом typeof.
Усвоив что всё есть обьекты, мы придём к первому правилу: все обьекты имеют динамически изменяемый интерфейс(читай ниже) Исключение: у стандартных встроенных в браузер обьектов нельзя подменить методы, т.е. у подобных обьектов(массивы, HTML элементы и т.п) есть свойствo "только для чтения", которое мы, как программисты использовать в наших обьектах не можем. Это всё нативные методы/свойства, выполняющие работу на "низком" уровне. На заметку: у обьектов есть только свойства Методы это тоже свойства обьектов(переменные), в которые записаны обьекты функции. Мы можем менять/добавлять метод как и любое другое свойство. Ссылка this будет указывать на обьект. При вызове функции не в контексте обьекта ссылка this указывает на обьект window. Другими словами все глобальные переменные и функции есть свойства обьекта window(хотя это не логично, хотели сделать обьект global, но у ИЕ заржавело...) На заметку: во многих языках есть понятие полей обьекта, при изменении которого вызывается функция обработчик(т.н. get/set функции). Изначально нетскейповцы придумали в стандартном интерфейсе Object(а следовательно у всех) методы watch/unwatch, следящие за обращениями к свойству обьекта и вызывающие функции обработчики. Под ИЕ это дело не пошло Мозилла "не оффициально" поддерживает __defineGetter__|__defineSetter__. Пример можно увидеть здесь ИМXО хорошая и удобная вещь для создания свойств только для чтения. К сожалению сейчас пока нет универсального единого способа сделать свойства обьекта "только для чтения". Впервые достала фича форума, если время между постами меньше 5 минут, посты сливаються. Мешает... -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
Sardar |
|
||||||
Бегун Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Эффективный интерфейс обьекта.
Любой обьект имеет определённый интерфейс - список всех свойств обьекта(выше мы обусловились что методы это свойства/поля обьекта ). Интерфейс обьекта может менятся во время выполнения. Мы также уточнили иключение для нативных обьектов из этотого утверждения(зачем и как нам переопределять window.open? ). Теперь поговорим от том как же формируется интерфейс обьекта. Рекомендуется выспаться, пробежать пару км. для бодрости, выпить кофе Определение вложенных функций и наследование контекста. Если в теле одной функции определить вторую функцию, то все переменные доступные в контексте первой функции доступны и в контексте вложенной. Это очень удобно, например для создания различных обработчиков для обьектов, нам не нужно создавать какие то внешние регистры в которых придётся запоминать ссылки на обьекты. Исключение: ссылка this и arguments являются личными для каждой функции и не наследуются по контексту.
Замечаем что переменные lnkи parg также доступны и ниже по контексту в новой функции. Также видим что this и arguments у каждой функции свои, для имортирования их ниже по контексту, нужно создать на них ссылки с другими именами. При вызове test как конструктора, в this храниться ссылка на только что созданный обьект. При вызове a() мы вызываем функцию в глобальном контексте, т.е. this в a указывает на window. Поэтому alert(this.field) выдаст undefined. При вызове test как простую функцию this указывет на window, т.е. мы создаём новую переменную в глобальном контексте с именем field. Как и ранее a вызывается в глобальном контексте, потому field нам доступна. Важно: из теста видно что мы наследуем контекст, т.е. все переменные с их текущими значениями. При следующем вызове эти переменные поменяют свои значения, но тем не менее в созданной функции они продолжают содержать "старые" значения. На самом деле при каждом вызове test создаётся новая функция a! Которая и содержит актуальные значения. Убедитсься мы в этом можем следующим кодом:
Может показаться не эффективным вот так транжирить память, но на самом деле всё работает правильно при правильном проектировании программы На заметку: на самом деле в хорошем интерпретаторе(а плохие быстро умирают ) код функции не дублируется, просто разным "копиям" присваивается ссылка на свой контекст, хранящий все "унаследованные" переменные. Механизм похож на вложенные анонимные классы в Java. Теперь более реальные примеры, создание "делегатов", например для вставки их как параметры у window.setTimeout. Напомню что set(Timout|Interval) работает только с обьектом функцией. Делегат в нашем случае это функция содержащая сылку на обьект и метод, который вызывается при её вызове.
Как видим сохранение контекстов в создаваемых функциях очень удобно, когда нужно определять каких то уникальных обработчиков для обьектов. Например для создания обработчиков событий для элементов страницы. И так в этой точке должно быть ясно что:
-------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||||
|
|||||||
Sardar |
|
||||
Бегун Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: 78 Всего: 317 |
Задание интерфейса обьекта в функции(конструкторе).
Теперь мы знаем что есть обьекты и что есть функции и контексты. Рассмотрим такой код:
Если в этот момент уже потерял способность думать, прими душь, потом продолжим Представим что мы интерпретатор, по шагам выполним код(опустим определение функции test):
Отсюда понятно почему мы извне не можем обратиться к локальным переменным конструктора, а все созданные внутри него функции доступ до них имеют(имеют ссылку на его контекст, бывший текущим в момент их создания). Важно: повторю все созданные внутри конструктора функции это самостоятельные обьекты, т.е каждый новый обьект от test имеет свои собственные функции-методы, которые содержат одинаковый код. Это в корне отличается от других ООП языков, где обьекты являються экземплярами класса и все имеют один и тот же код в методах(код храниться в классе). В JS каждый обьект с методом созданным как показано выше получает свой собственный обьект-метод(код храниться в обьекте). Что бы было еще более ясно о локальных переменных конструктора(на них мы потом будет делать "приватные" поля обьекта), дополним предидущий код:
Как видим созданный method2 уже не имеет доступа к локальным переменным конструктора. Для справки: все созданные свойства обьекта являются его личными(сохраняются в его памяти, другой обьект может их не иметь). Метод method2 мы добавили уже после того как конструктор отработал, это тоже личное свойство обьекта. Нет никакой разницы между определением свойства в конструкторе и вне конструктора, используеться один и тот же механизм динамически создаваемых свойств обьектов. Различии появяться когда мы приступим к прототипам Предлагаю сделать паузу -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
Aliance |
|
|||
I ♥ <script> Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 55 Всего: 137 |
||||
|
||||
Се ля ви |
|
||||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 5 Всего: 127 |
Напрямую - нет, но как насчёт методов get/set и инкапсуляции на основе замыканий? Представляем свойство в виде двух методов - getFieldName и setFieldName - и делаем это так:
-------------------- |
||||
|
|||||
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |