Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.05.2013, 08:33
Интересующийся
Отправить личное сообщение для seyfer Посмотреть профиль Найти все сообщения от seyfer
 
Регистрация: 16.11.2012
Сообщений: 16

Метод наследования не работает для цепочки 3 и более объектов. Почему?
У меня есть 3 объекта.

netBuilder Numbering NumberingMethodDefault

Метод наследования взят с местной статьи.

http://javascript.ru/tutorial/object/inheritance

Ф-я extend и mixin.

extend: function (Child, Parent) {
  var F = function () {};
  F.prototype = Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child;
  Child.superclass = Parent.prototype;
  this.mixin(Child, Parent);
},
/**

 * @param {type} dst
 * @param {type} src
 * @returns {undefined}
 */
mixin: function (dst, src) {
  var tobj = {};
  for (var x in src) {
    if ((typeof tobj[x] == "undefined") || (tobj[x] != src[x])) {
      dst[x] = src[x];
    }
  }
  if (document.all && !document.isOpera) {
    var p = src.toString;
    if (typeof p == "function" && p != dst.toString && p != tobj.toString &&
      p != "\nfunction toString() {\n    [native code]\n}\n") {
      dst.toString = src.toString;
    }
  }
}


Я делаю наследование
Numbering extends from netBuilder
NumberingMethodDefault extends from Numbering.

oopUtility.extend(Numbering, netBuilder);
oopUtility.extend(NumberingMethodDefault, Numbering);


И вызываю где надо суперклассы конечно же.

Numbering.superclass.constructor.apply(this, arguments);
NumberingMethodDefault.superclass.constructor.apply(this, arguments);


Numbering имеет метод setNumber(). У меня есть доступ в Numbering к netBuilder методам, но в NumberingMethodDefault я не могу выполнить метод из Numbering setNumber().

Uncaught TypeError: Object #<NumberingMethodDefault> has no method 'setNumber'


Тогда я вывел console.log() что же в суперклассе NumberingMethodDefault

console.log(NumberingMethodDefault.superclass);
//and it was netBuilder, not Numbering! о_О


Там почему-то netBuilder, а не Numbering. Хотя в статье описывается, что должно работать с цепочкой и в 3 объекта.

Как заставить работать наследование для цепочки 3 и более?

Последний раз редактировалось seyfer, 21.05.2013 в 08:40.
Ответить с цитированием
  #2 (permalink)  
Старый 21.05.2013, 08:34
Интересующийся
Отправить личное сообщение для seyfer Посмотреть профиль Найти все сообщения от seyfer
 
Регистрация: 16.11.2012
Сообщений: 16

И да, я пробовал

NumberingMethodDefault.superclass.setNumber.call(this, arguments);


Но очевидно получал ошибку, т.к. в netBuilder нет такого метода.
Ответить с цитированием
  #3 (permalink)  
Старый 21.05.2013, 10:05
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

А у экземпляров Numbering-то setNumber вызывается?

Вы, вероятно, сначала описываете Numbering и его прототип, а потом наследуетесь. Так делать неправильно, ибо extend перезаписывает прототип.
var oop = {
extend: function (Child, Parent) {
  var F = function () {};
  F.prototype = Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child;
  Child.superclass = Parent.prototype;
  this.mixin(Child, Parent);
},
/**

 * @param {type} dst
 * @param {type} src
 * @returns {undefined}
 */
mixin: function (dst, src) {
  var tobj = {};
  for (var x in src) {
    if ((typeof tobj[x] == "undefined") || (tobj[x] != src[x])) {
      dst[x] = src[x];
    }
  }
  if (document.all && !document.isOpera) {
    var p = src.toString;
    if (typeof p == "function" && p != dst.toString && p != tobj.toString &&
      p != "\nfunction toString() {\n    [native code]\n}\n") {
      dst.toString = src.toString;
    }
  }
}
};

function netBuilder() {

}

function Numbering() {

}
*!*
oop.extend(Numbering, netBuilder);
*/!*
 // важно отнаследоваться здесь, а не после объявления прототипа!

Numbering.prototype.setNumber = function() {
  alert('Numbering#setNumber');
}

function NumberingMethodDefault() {

}
oop.extend(NumberingMethodDefault, Numbering);

new NumberingMethodDefault().setNumber();

Последний раз редактировалось B@rmaley.e><e, 21.05.2013 в 10:52.
Ответить с цитированием
  #4 (permalink)  
Старый 21.05.2013, 10:43
Интересующийся
Отправить личное сообщение для seyfer Посмотреть профиль Найти все сообщения от seyfer
 
Регистрация: 16.11.2012
Сообщений: 16

Сообщение от B@rmaley.e><e Посмотреть сообщение
А у экземпляров Numbering-то setNumber вызывается?

Вы, вероятно, сначала описываете Numbering и его прототип, а потом наследуетесь. Так делать неправильно, ибо extend перезаписывает прототип.
1) Вызывается. И как у объекта и через this внутри объекта.

2) Методы описаны не через прототип, все внутри через this.

this.setNumber = function(elem, row, number);

Последовательность подключения js файлов верная, следовательно и последовательность вызовов extend.
Т.е последовательность: netBulder, Numbering, NumberingMethodDefault. extend вызывается в последних 2-х файлах после объявления объекта. Проблема в том, что все методы в this ?


Numbering.prototype после extend уже равен netBuilder же.

console.dir(Numbering.prototype);
//netBuilder


Если я буду добавлять в прототип после, то это уже добавление метода в netBuilder получается. Или идея как раз в том, что у всех общий прототип?

Последний раз редактировалось seyfer, 21.05.2013 в 10:47.
Ответить с цитированием
  #5 (permalink)  
Старый 21.05.2013, 10:54
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Сообщение от seyfer
Проблема в том, что все методы в this ?
Проблема в том, что конструктор родительского класса не вызывается. Наследуются только прототипные методы.
Ответить с цитированием
  #6 (permalink)  
Старый 21.05.2013, 11:00
Интересующийся
Отправить личное сообщение для seyfer Посмотреть профиль Найти все сообщения от seyfer
 
Регистрация: 16.11.2012
Сообщений: 16

Сообщение от B@rmaley.e><e Посмотреть сообщение
Проблема в том, что конструктор родительского класса не вызывается. Наследуются только прототипные методы.
Кхм. Почему же тогда у меня нет проблем между netBuilder и Numbering? Все методы через this. вызываются.

На stackoverflow мне подсказывают, что проблема в mixin.
Он копирует же все родительские свойства, в том числе перетирает superclass.
Надо добавить туда проверку не копировать superclass, это скорее всего решение.
Ответить с цитированием
  #7 (permalink)  
Старый 21.05.2013, 12:19
Интересующийся
Отправить личное сообщение для seyfer Посмотреть профиль Найти все сообщения от seyfer
 
Регистрация: 16.11.2012
Сообщений: 16

Вот решение проблемы.

if (((typeof tobj[x] == "undefined") || (tobj[x] != src[x])) && (src[x] != src.superclass)) {
                dst[x] = src[x];
            }


Суперкласс теперь не перетирается родительским и наследование работает правильно. Надо написать автору статьи.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Предложение представить код с setInterval для n - но более двух DOM-єлементов JavaScriptProgrammer Events/DOM/Window 1 09.11.2012 08:09
JSON или JSONP для запросов на другой сервер? Метод GET, для длинных сообщений? Kotakota jQuery 5 23.08.2011 23:12
$('#id') не работает для некоторых элементов tmvrus jQuery 10 12.10.2010 15:45
Почему "display:block" не работает для <A> в ИЕ 6,7 и Maxthon? warobushek (X)HTML/CSS 2 29.04.2010 07:51
Почему не работает функция? Vitaly jQuery 10 31.07.2009 17:01