ООП: как создавать наследника от встроенных объектов?
Добрый день.
Объясните новичку, как должен выглятедь конструктор, который будет создавать объекты наследующие свойства встроенных объектов? Чтобы уже в этом конструкторе была возможность переопределять и добавлять новые свойства. Например чтобы массив создавался не через new Array, а через new myArray. Спасибо. |
Цитата:
http://wdh.suncloud.ru/js07.htm http://javascript.ru/forum/events/2641-object.html конструктор будет выглядеть Код:
function Circle(radius) { JavaScript поддерживает наследование, основанное на прототипах. С каждым конструктором связан соответствующий прототип объекта, и каждый объект, созданный конструктором, содержит неявную ссылку на этот прототип. Прототип, в свою очередь, может содержать ссылку на свой прототип и так далее. Так образуется цепочка прототипов. Ссылка на свойство объекта — это ссылка на первый прототип в цепочке прототипов объекта, который содержит свойство с данным именем. Иными словами, если данный объект имеет свойство с данным именем, то используется ссылка на это свойство; если нет, то исследуется прототип этого объекта и т. д. В JavaScript текущее состояние и методы реализуются объектами, а структура и поведение наследуются. Все объекты, которое явно содержат свойство, которое содержит их прототип, разделяют это свойство и его значение. В отличие от языков, основанных на классах, свойства могут динамически добавляться к объектам и динамически удаляться. В частности, конструкторы не обязаны присваивать значения всем или некоторым свойствам создаваемого объекта. p.s. вас googl'ом пользоваться не учили ?:D |
Боюсь, что прозрачный интерфейс (или прокси) для встроенных классов у вас сделать не получится.
|
q--b, недавно разобрался с javascript-oop и уже поучаешь?
Цитата:
Цитата:
|
x-yuri,
Может я просто не додумался, но попробуй сделать свой объект, который будет расширять, например, Array, при этом сохраняя его функциональность, как массива. |
Большое спасибо за ответы.
2x-yuri, уже 2 дня медитирую как раз над указанной вами статьей о наследовании. С пониманием принципов наследования через прототипы все в порядке. Но попытки создать класс, который бы унаследовал все свойства объекта Array, чтобы не переопределять методы самого Array, а дабавлять их к созданному классу не получилось. По видимому не могу уловить какие то базовые принципы. 2Андрей Параничев Только что в ветке "10 лучших функций на JavaScript" обнаружил в комментариях такой код: ArrayUtils.inArray = (Array.prototype.indexOf) ? function (/* Array */a, /* Mixed */val) { return a.indexOf(val) != -1; } : function (/* Array */a, /* Mixed */val) { var i = a.length; while (i--) { if (a[i] === val) return true; } return false; } разве это не реализация того самого "прозрачного" интерфейса? 2q--b Спасибо за подробный ответ. Давайте только причины и способы изучения ООП оставим на моей совести. |
Langalier,
Не совсем то, что я имел в виду, вот например попробуем создать конструктор myArray, который бы выдавал нам массив, но имел расширенные (перегруженные) методы работы с элементами. Далеко ходить не будем, возьмем функцию из статьи: function extend(Child, Parent) { var F = function() { } F.prototype = Parent.prototype Child.prototype = new F() Child.prototype.constructor = Child Child.superclass = Parent.prototype } Теперь напишем конструктор объектов myArray: var myArray = function() { this.getLastElement = function() { return this[this.length-1]; } } // И наследуем массив: extend(myArray, Array); Посмотрим, что получилось: // Создадим наш объект: var a = new myArray(); // Добавим ему элементов, через свойства: a[0] = "Привет"; a[1] = "Мир"; // Пробуем alert(a.getLastElement()); // undefined - ничего // А длина? alert(a.length); // 0 - пусто // Теперь добавим через методы: a.push("Пока"); a.push("Ад"); // Пробуем alert(a.getLastElement()); // "Ад" // А длина? alert(a.length); // 2, все в порядке Другими словами, вам не удастся наследовать всю функциональность массивов, когда добавление элемента напрямую увеличивало длину массива. |
Цитата:
|
Цитата:
но что IE хочет? O_o если унаследоваться от Array то нельзя изменить свойство length объекта Langalier, повторюсь, для чего собственно нужно наследоваться от массива? а вообще вижу такие варианты: 1) создать внешний объект (типа ArrayUtils), который будет выполнять дополнительные операции над массивами 2) добавлять функциональность в созданные массивы (arr.getLastElement = getLastElement) 3) сделать класс-обертку типа jQuery ($(arr).getLastElement()) 4) добавлять методы в Array.prototype, но это крайняя мера. Из-за этого, наверняка, перестанет корректно работать код обходящий массивы с помощью for...in |
Андрей Параничев
Спасибо. Очень помогло пониманию. x-yuri Если я правильно понимаю, то скорее 3 вариант. |
Вот только хотел залезть на форум с таким же вопросом и наткнулся на это обсуждение. Жаль, что непонятки с наследованием от Array так и не разрешены :(
Может все дело в самом свойстве length? Честно говоря мне не понятно, как оно обновляется, т.е. как отслеживается сам момент добавления к массиву нового элемента. Есть ли в языке механизм, позволяющий отследить это событие или это реализовано на уровне недоступном программисту? А в остальном наследование от прототипа вроде работает корректно? |
Цитата:
Цитата:
Цитата:
|
function myObj(){
... }; myObj.prototype = Array.prototype; var x = new myObj(); x[0] = 5; Разве в этом случае x получает свой метод [[Put]](P, V) не от объекта Array.prototype? Если да, то свойство length должно обновляться нормально? Кстати, я так привязался к наследованию потому, что в этом и состоит цель - разобраться с наследованием :) |
Цитата:
Цитата:
|
[[Put]] - это специальный метод, и вряд ли он в каком-нибудь браузере по цепочке прототипов ищется
function myObj() {} myObj.prototype = new Array(); var x = new myObj(); x.__proto__[0] = 5; alert(x.__proto__.length); вот такая штука, например, работает в ff, но есть же еще ie, у которого я не знаю как к прототипу обратится. Но у него даже вручную length изменить нельзя |
Читал, но там все больше свойства к прототипу цепляют...
А хочется свой класс сделать Вариант с __proto__ не нравится. Этак можно просто сделать x.arr = [] x.arr[0] = 5; alert(x.arr.length) .... Но какое ж это наследование. Может проблема в подходе. В JavaScript просто плохо применимы методы ооп из типизированных языков, а нужно действовать по другому? |
фактически, в javascript нету классов, а наследование построено на прототипах. Классы можно только эмулировать и по-разному, а можно не эмулировать
Прототипное программирование — стиль объектно-ориентированного программирования (может не очень достоверный источник, но вот http://ru.wikipedia.org/wiki/Про...ова ие) еще есть такие варианты http://ejohn.org/blog/simple-javascript-inheritance/ http://dean.edwards.name/weblog/2006/03/base/ http://javascript.crockford.com/inheritance.html http://javascript.crockford.com/prototypal.html |
Спасибо за ссылочки
Теперь понятно откуда ноги растут :) |
Часовой пояс GMT +3, время: 07:51. |