Hi!
Не приятная фишка

Все браузеры дают одно, так что это фишка а не баг...
может кто-нибудь объяснить вывод этого скрипта?
<script>
function cl(x){
alert(this.i[0]+','+this.j[0]);
this.i.push(x);
}
cl.prototype={
i:[],
j:[0]
}
var a=new cl(1);
var b=new cl(2);
</script>
undefined,0
1,0
Обнаружил чисто случайно. после того как раз 20 все переписал с нуля, увершал все что можно затычками и пр. Очень забавно получилось — управляешь одним объектом, а реагирует другой

только по тому и нашел.
Попутно задам вопрос: вы как пишите (если пишите много)?
// 1 (-) очень много писанины, довольно слепо
// (-) конструктор создает все поля объекта, а не берет готовый объект и инициализирует его.
function cl(){
this.a=0;
this.f=f;
// объявили все поля в начале, потом конструктор и вложенные функции
function f(){}
}
// 2 (-) ни хрена не понятно :) но чаще всего именно так
function cl(){
this.a=0;
// где надо там и создали поле
this.f=function(){}
}
// 3 (+) минимум писанины, предельно структурированно и понятно
// (-) debuger часто не может поставить breakpoint на середину функции f() (получается на весть cl.prototype=...)
// (-) в debuger в стеке вызовов надписи про анонимную функцию, а не ее имя.
// (-) пока это туго понимают редакторы
// (?) если бы ни штука о которой я писал выше, то так бы было удобнее всего. а так - прийдется переписывать 60кб убористого кода 15 классов... :crash:
function cl(){ this._construct(); }
cl.prototype={
a:0;
f:function(){}
}
Здравствуйте, DPP, Вы писали:
На самом деле описанные пример совсем не фишка и даже не ошибка, а вполне закономерные результат.
Сравним со следующим примером, чтобы понять почему произошла описанная ситуация:
<script>
function mycl(x)
{
this.i = [];
this.j = [0];
alert(this.i[0]+','+this.j[0]);
this.i.push(x);
}
var a=new mycl(1);
var b=new mycl(2);
</script>
Данные код создает два объекта a и b с полями i = [], j = [0]. Обращаю внимание что эти
объекты отличаются от объектов в исходном примере. И отличаются они ровно своими полями.
В исходном примере поля i и j создавались на этапе объявления прототипа объекта. Это
значит что сколько бы экземпляров мы не создавали — эти поля изначально будут ссылаться
на одни и те же объекты — массивы. В моем примере мы создаем поля в конструкторе и
следовательно сам прототип ничего не знает об этих полях, хотя они и есть в объектах.
Фактически, исходное объявление класса более корректно, т.к. каждый экземпляр класса будет
точно иметь нужные поля. Но при таком объявлении надо помнить о инициализации полей в
конструкторе, чтобы не получить трудноуловимые ошибки. В моем случае я могу создать,
а могу и не создавать некоторые поля, например в зависимости от параметров конструктора.
Ответ на вопрос, о том кто и как пишет.. Это конечно на любителя, но я пишу так:
function A(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
A.prototype.xy = function()
{
return x * y;
}
A.prototype.yz = function()
{
return y * z;
}
Почему так, а не иначе:
1) Объявление полей в конструкторе позволяет избежать ситуации описанной в исходном примере,
если подобное поведение не является необходимым.
2) Отдельное объявление каждого метода — наверное спорно, но мне кажется так легче читать код,
особенно когда методы большие и их много — сразу понятно чей это метод. И еще один аргумент —
при таком подходе очень легко выдергивать некоторые методы из основного кода и выносить их в
отдельные файлы или дописывать новые методы и подключать их из дополнительных файлов. При этом
весь код, и основной, и в дополнительных файлах выглядит одинаково, что упрощает его чтение.
Здравствуйте!
Несмотря на то, что вы создаёте два разных экземпляра, внутри конструктора вы "управляете" общим для них обоих объектом-прототипом, его свойствами, т.к. непосредственно у экземпляров нет своих "собственных" свойств с именами i и j. Всё стандартно.
— При первом вызове конструктора массив i пустой, поэтому в алерте undefined.
— Перед выходом из конструктора заталкиваем в массив i элемент со значением 1.
— При втором вызове конструктора в алерте виден тот самый первый элемент со значением 1.
Пара ссылок на эту тему и на тему подходов к созданию экземпляров:
http://weblogs.asp.net/bleroy/archive/2006/10/07/Careful-with-that-prototype_2C00_-Eugene.aspx
http://weblogs.asp.net/bleroy/archive/2006/10/11/From-closures-to-prototypes_2C00_-part-1.aspx
http://weblogs.asp.net/bleroy/archive/2006/10/14/From-closures-to-prototypes_2C00_-part-2.aspx