наследование в javascript
Добрый день!
Подскажите пожалуйста, почему следующий код так работает: var todayTimeTable = new timeTable(); function timeTable(){ this.showHeader = function(){ document.write("Расписание на сегодня<br />"); } } timeTable.prototype = new Array; timeTable.prototype.showFirst = function(){ document.write(this[0]); } // var todayTimeTable = new timeTable(); - если создать объект здесь,то все методы работают todayTimeTable.showHeader(); //Расписание на сегодня todayTimeTable.push("Информатика"); // ошибка todayTimeTable.push is not a function todayTimeTable.showFirst(); Точнее интересуют следующие вопросы: почему объект в первой строке создается без проблем, хотя его "класс" описывается ниже? почему в созданный объект не попадают методы, которые имеются в прототипе? Если создать объект в коде ниже строк описывающих наследование, то объект будет содержать все методы. Возможно, это простые вопросы, но я не могу самостоятельно найти на них ответы, помогите, пожалуйста, разобраться. |
Прототип !== объект. Если вы сделали прототипом объекта массив, сам он от этого массивом не станет. Поэтому метод push и не работает.
|
Цитата:
|
А при чем тут наследование?
|
Цитата:
|
Ну на самом деле во всех современных движках он станет почти массивом, так как особые Сеттеры, про которые говорили в соседней теме - пронаследуются. Правда в v8 например этот объекта не удастся использовать как массив для передачи параметров в метод apply. Это можно посмотреть в исходных кодах, выглядит примерно так:
function apply(object, array){ if(!Array.isArray(array) || !array instanceof Arguments) throw new TypeError('...'); // ... } Естественно там внутренние методы используются, хотя isArray тоже вернёт волс на самом деле. В то время как в SpiderMonkey вернёт тру, если не ошибаюсь. Там полностью наследуется поведение массива. То есть такой новый объект и есть массив. |
Цитата:
И делать объект массивом всё же не нужно, на мой взгляд. Зачем?) |
Первый раз парсер пробегается по коду, запоминая function, не заглядывая во внутренности. Т.е. пробежавшись, он знает, что timeTable есть. Поэтому ошибки не возникает и присваивание происходит.
Я у себя попроверял. Если прототип классу присваивается после создания объекта, объект остается без данных прототипа... Спецификацию не читал, если кто читал - буду рад услышать комментарий по этому поводу. function Animal(name) { this.name = name this.canWalk = true } function Rabbit(name) { this.name = name } big = new Rabbit('Chuk') Rabbit.prototype = new Animal("скотинка"); small = new Rabbit('Gek') alert(big.canWalk); alert(small.canWalk); |
trikadin,
Ну я и написал, что не кроссбраузерно, даже привёл пример с v8. А нужно это было мне, для матриц в WebGL, можно выкрутиться там конечно по другому, на так было бы красивее :) |
Snipe,
Ну видимо, тут дело в том, что для того, что бы расширять уже существующие объекты, нудно расширять прототип, а не заменять его. Заменяя прототип, вы фактически создаёте новый класс. Берём ваш пример и смотрим: function Animal(name) { this.name = name this.canWalk = true } function Rabbit(name) { this.name = name } big = new Rabbit('Chuk') Rabbit.prototype = new Animal("скотинка"); small = new Rabbit('Gek') alert(big instanceof Rabbit) alert(small instanceof Rabbit) По хорошему конечно, наследование нужно организовывать приблезительно так: var create = Object.create || (Object.create = function(proto){ var constructor = function(){}; constructor.prototype = proto; return new constructor; }), inherit = function(childHandler, parent){ var child = function(){ parent.apply(this, arguments); childHandler.apply(this, arguments); }; child.prototype = create(parent.prototype); child.prototype.__parent__ = parent; return child; } var A = function(){ this.foo = 1; }, B = inherit(function(){ this.bar = 2; }, A), c = new B(); alert(c instanceof B); alert(c instanceof A); |
Часовой пояс GMT +3, время: 10:25. |