Loading...

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

velio84 avatar velio84 241 Точки

[Homework] Advanced JS - Prototype Chain and Inheritance

Имам проблем с 2-ра задача.

Ето го кода

Проблема ми е във функцията за създаване на сегмент (редове 95-104).

Тъй като линията и сегмента имат еднакви пропъртита (A[x,y], B[x,y], color) - искам сегмента просто да наследи линията.

Като го мина през дебъгера, излиза че проблема е когато тръгна да създавам init на segment (97 ред), програмата отива в конструктора на line (базовия клас за segment, ред 80) и там зацикля с

"too much recursion" в браузъра и

"RangeError: Maximum call stack size exceeded" в nodejs

laughing

струва ми се, че проблема е някъде в this-овете, но не съм сигурен...

Някакви идеи? :)

2
JavaScript Advanced 13/03/2015 02:35:44
RoYaL avatar RoYaL Trainer 6849 Точки

Наследяването на повече от едно ниво не ти работи никъде. Пробвай да наследиш примерно триъгълника, който наследява шейп и ще видиш, че ще се случи същото.

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

if (this._super) {
f.prototype._super = this._super;
} else {
f.prototype._super = this;
}
0
Filkolev avatar Filkolev 4482 Точки

Проблемът е тук: this._super.init.call(this, x1, y1, x2, y2, color);

Във всеки обект го имаш това, оправи го и ще проработи: this._super.init(x1, y1, x2, y2, color);

Ти си дефинирал _super като обект от класа родител, т.е. викането на метод на super става директно.

call/apply се ползват, когато искаш да извикаш дадена функция отвън (например да приложиш Array.splice върху обект, който не е масив, а е array-like); в случая, имайки обекта родител, ти просто си викаш функцията върху него.

4
velio84 avatar velio84 241 Точки

Благодаря, проработи така :)

Явно ще трябва да излгледам и лекцията - само с гледане на примерите не ми се получава :D

0
13/03/2015 11:38:33
Dominik avatar Dominik 82 Точки

Здравейте,

Имам малък проблем с 1-ва задача от домашното.

Проблема е следният в парент класа  ( Shape ) имам .toString метод закачен за прототипа, който работи нормално.

Това е кода в Shape ( parent ) на toString метода. 

Shape.prototype.toString = function () {

return "X: " + this._x + " Y: " + this._y;
};

След това в отделен файл наследявам Shape и опитвам да override-на toString метода, но ми гърми със следната грешка в конзолата на браузъра  - "undefined is not a function"

Ето го Rectangle класа, с който наследявам Shape Rectangle

Някакви идеи къде бъркам ? 

Благодаря предварително.

 

0
RoYaL avatar RoYaL Trainer 6849 Точки

worldObject.Shape.toString.call

би трябвало да е

worldObject.Shape.prototype.toString.call

1
Filkolev avatar Filkolev 4482 Точки

Имаш ли ги и двата файла инклуднати? Вторият за да ползва първия трябва да може да го вижда. Също с това IIFE, което не пазиш никъде може да има проблем, то се изпълнява, но после как създаваш обект? Мисля, че трябва да го бутнеш в някаква променлива, за да бачка, иначе се изпълнява и изчезва в небитието, освен ако не пропускам нещо.

В единия сетър имаш изтървана долна черта, което може да доведе до овърфлоу: this.height = height. Не съм го тествал, но е вероятно да викаш рекурсивно сетъра до безкрай.

А, то всъщност и сетъра е грешно кръстен, имаш два пъти сетър за width...

0
13/03/2015 17:03:01
Dominik avatar Dominik 82 Точки

Благодаря RoYaL получи се.

@Фил ами това с повтарящият се сетър е copy-paste грешка благодаря щях да се чудя по-късно защо се получава така :).

Иначе аз закачам резултата от IIFE-то на променливата worldObject, която имам във всеки един от файловете (поне така видях, че направи Влади на лекцията в Четвъртък) резултата не се загубва поне до сега. Ако има някакъв по хитър и лесен начин може да го сподели някой :).

0
a.polyanska avatar a.polyanska 107 Точки

Здравейте,

И аз ще използвам да попитам- не съм и стигнала още до втората задача и страшно се оплетох. Ето го кодът- само до кръг стигнаха опитите ми :(

Като резултат ми излиза "NaNcolor: 5", т.е. изпълнява само половината "toString" и то в частта, която наследява от Shape. Не мога да се ориентирам какво се случва и като дебъгвам. Някой ще ми даде ли насоки какво се случва? (Пробвах и да махна call от toString-a на кръга, но същото ми се получава)

Благодаря!

0
16/03/2015 23:09:09
Filkolev avatar Filkolev 4482 Точки

Пробвай да сложиш "return Circle" накрая, след закачането на toString към прототипа.

0
a.polyanska avatar a.polyanska 107 Точки

Хммм, сега изкарва само радиуса правилно. Резултатът е "NaNcolor: undefined, r = 7"

0
Filkolev avatar Filkolev 4482 Точки

Имаш излишна запетайка в toString на Shape след this._x. Махни я и ще се оправи. Липсва и един спейс преди color, той лесно се слага, но тая запетайка много трудно я видях.

1
Filkolev avatar Filkolev 4482 Точки

Ето моите решения на двете задължителни задачи: ЛИНК.

За съжаление няма да имам време да направя другите две, тия дни тичам напред-назад и се занимавам с глупости...

Имам няколко въпроса.

  • По 1-ва задача, реших да сложа някакви валидации (на 2-ра ги пропускам, не ми се занимава пак да ги правя). Направих ги обикновени функции, не исках да слагам някакви изчанчени пропъртита. Това обаче означава, че трябва да подавам като аргумент и самия обект, за да мога да му сетна стойността. Някой може ли да предложи по-кадърен начин да го направя това?
  • Реших, че отсечката трябва да ми наследява правата, за да се спести повторение на малко код (те двете са еднакви по дефиницията на условието). Обаче във 2-ра задача стигам до прекрасния ред: result += this._super._super.toString() - бъркам два пъти навътре в _super, за да стигна toString на shape.
  • Като цяло в shape/Shape имам само color. Ако правих задачата на C# бих направил клас точка и за всяка фигура да има списък от точки, но в случая за всяка конкретна фигура задавам директно координатите. Някой да го е направил с клас точка и масив от точки? Видях варианти, в които фигурата има някакви координати, но не ми се струва много чисто.

Други препоръки са добре дошли.

1
dim4o avatar dim4o 288 Точки

Аз го направих с точка и двете. Така ми се стори по-логично. И аз реших че е по-добре триъгълника да наследи правата. Shape има point и color, защото това е общото между всички обекти. Така има градация: точка -> отсечка->затворен полигон. Ето ги двете задачи:

1. Geometry-PseudoClassical-Inheritance

2. Geometry-Prototype-Inheritance

С гетъри, сетъри и валидации стават 200 реда код. Освен това изглежда грозно, а логиката - трудна за проследяване. Но какво да се прави...

2
Filkolev avatar Filkolev 4482 Точки

Това, че всички фигури имат поне по една точка - така е, но излиза, че едната точка от триъгълника се счита за базова, а другите - някакви допълнителни, което не е много ясно като логика. По принцип с геометричните фигури са доста объркани нещата на моменти и трябва много да се внимава с наследяването.

Триъгълника да наследява правата не мисля, че е правилно, триъгълника не е вид права.

Иначе че излиза дълго - еми като сме свикнали да валидираме няма начин...

0
dim4o avatar dim4o 288 Точки

Според мен пък е доста логично. Фигурата с N точки наследява фигурата с N-1 точки, както отсечката наследява точката. Така новия конструктор има да добави само една точка. Триъгълника не е вид права но и правата не е вид точка. Или е - все е тая. Тези абстракции си ги правим да си услесним писането и има много модели - някои са по-интуитивни, а други не.

0
21/03/2015 00:12:49
goodlifeinc avatar goodlifeinc 31 Точки

Здравейте,

това е моето решение на втора задача: ЛИНК

Горе долу успях да я наглася, но не мога да се ориентирам как да направя проверка дали
circle наследява Prototypal.Shape ?

circle.init === Prototypal.Circle.init
circle._super.init === Prototypal.Shape.init

Тези двете проверки ми връщат true, но това ли е начина?

0
17/03/2015 11:10:49
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.