Мне не очень нравятся многоблочные определения псевдоклассов. Т.е. когда вначале определяют класс, блок закрывают, а затем определяют его прототип. Я решил попробовать определить прототип прямо в блоке класса. И столкнулся с полтергейстом:
Создан простой класс, в котором есть прототипная переменная, общая для всех экземпляров класса. Вызывается, через один экземпляр, функция, которая увеличивает общую переменную на 1. Затем выводится значение общей переменной для другого экземпляра.
<html><body>
<script>
function Test()
{
Test.prototype.data=1;
Test.prototype.f=function()
{
Test.prototype.data++;
}
}
test1=new Test;
test2=new Test;
test1.f();
document.write("test2.data=",test2.data,"<br>");
</script>
Всё верно, общая переменная поменялась — выводит: test2.data=2.
Отлично! Пробуем оптимизировать:
<html><body>
<script>
function Test()
{
Test.prototype=
{
data:1,
f:function()
{
Test.prototype.data++;
}
}
}
test1=new Test;
test2=new Test;
test1.f();
document.write("test2.data=",test2.data,"<br>");
</script>
Получаем: Uncaught TypeError: Object #<Test> has no method 'f'. WTF?!!
А если так:
<html><body>
<script>
function Test(){}
Test.prototype=
{
data:1,
f:function()
{
Test.prototype.data++;
}
}
test1=new Test;
test2=new Test;
test1.f();
document.write("test2.data=",test2.data,"<br>");
</script>
То работает! Но опять разбиваем на два блока верхнего уровня =(.
Вопросы:- Почему литеральная запись объекта внутри блока определения класса не работает, но работает присвоение там же но по полям? (Кстати с with внутри класса тоже не робит). Чем отличается присвоение по полям от литеральной записи?
- Почему, в таком случае, литеральная запись работает вне блока определения класса?
Поясните, кто знает механику работы объектов, я что-то не догоняю.