Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 07:58
Оценка:
Привет.

Как я уже успел узнать, классы в js можно эмулировать кучей различных способов, один извращённее другого.

1.
function MyClass() {
  this.field1 = 666;
  this.method1 = MyClass_method1();
  this.method2 = MyClass_method2();
  // ...
}

function MyClass_method1(x) {
  alert("MyClass_method1");
}

function MyClass_method2(x) {
  alert("MyClass_method2");
}

Каждый раз перенабирать имя класса в имени "метода" наводит грусть. "Методы" болтаются отдельно. И почему используется NewClass_method1() вместо NewClass_method1 в конструкторе? В конце концов в javascript функции FCO или не FCO?

2.
function MyClass() {
  this.field1 = 666;
}
MyClass.prototype.method1 = function(x) {
    alert("MyClass_method1");
}
MyClass.prototype.method2 = function(x) {
  alert("MyClass_method2");
}

Уже лучше, но раздражает слово prototype. И имя класса каждый раз нужно снова повторять. И методы опять как-то нехорошо отделены от класса.

3.
function MyClass() {
  this.field1 = 666;

    MyClass.prototype.method1 = function(x) {
        alert("MyClass_method1");
    }

    MyClass.prototype.method2 = function(x) {
        alert("MyClass_method2");
    }
}

Одним недостатком меньше — код компактен, но попугайское повторение одного и того-же имени класса и слова prototype портят весь кайф.

4.
function MyClass() {
  this.field1 = 666;

  this.method1 = function(x) {
        alert("MyClass_method1");
  }

  this.method2 = function(x) {
        alert("MyClass_method2");
  }
}

Самый чистый и опрятный вариант, но и тут оказываются грабли. Оказывается, мегадвижки не в состоянии соптимизировать код и прям-таки вынуждены плодить по новой функции на каждый экземпляр. Ужос, просто.

В связи с этим у меня 4 вопроса:
1. Функции в javascript первоклассные или нет?
1. Какой способ определения класса выбирают РСДН-гуру?
2. Почему оптимизация в пункте 4 невозможна? Что мешает?
3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2

Спасибы.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Классы в Javascript
От: Mamut Швеция http://dmitriid.com
Дата: 10.04.08 08:24
Оценка: 12 (1)
LCR>В связи с этим у меня 4 вопроса:
LCR>1. Функции в javascript первоклассные или нет?

Да. В этом отношении Javascript — полноценный функциональный язык.

LCR>1. Какой способ определения класса выбирают РСДН-гуру?


Я не гуру , но использую 4-й способ Большниство всяких фреймворков, насколько знаю, используют его же

LCR>2. Почему оптимизация в пункте 4 невозможна? Что мешает?

LCR>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2

На эти два вопроса, увы, ответов не имею
... << RSDN@Home 1.2.0 alpha 4 rev. 1064>>


dmitriid.comGitHubLinkedIn
Re[2]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 10:14
Оценка:
Mamut,

LCR>>В связи с этим у меня 4 вопроса:

LCR>>1. Функции в javascript первоклассные или нет?

M>Да. В этом отношении Javascript — полноценный функциональный язык.

А вот почему тогда пишется
  this.method1 = MyClass_method1()
  this.method2 = MyClass_method2()

а не
  this.method1 = MyClass_method1
  this.method2 = MyClass_method2

По мне например, MyClass_method1() выглядит как вызов без аргументов.

LCR>>1. Какой способ определения класса выбирают РСДН-гуру?


M>Я не гуру , но использую 4-й способ Большниство всяких фреймворков, насколько знаю, используют его же


То есть можно не париться с чрезмерным расходом памяти. Спасибо, это хорошая новость

LCR>>2. Почему оптимизация в пункте 4 невозможна? Что мешает?

LCR>>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2

M>На эти два вопроса, увы, ответов не имею


Спасибо и на том
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[3]: Классы в Javascript
От: Mamut Швеция http://dmitriid.com
Дата: 10.04.08 10:19
Оценка:
LCR>>>В связи с этим у меня 4 вопроса:
LCR>>>1. Функции в javascript первоклассные или нет?

M>>Да. В этом отношении Javascript — полноценный функциональный язык.

LCR>А вот почему тогда пишется
LCR>
LCR>  this.method1 = MyClass_method1()
LCR>  this.method2 = MyClass_method2()
LCR>

LCR>а не
LCR>
LCR>  this.method1 = MyClass_method1
LCR>  this.method2 = MyClass_method2
LCR>

LCR>По мне например, MyClass_method1() выглядит как вызов без аргументов.

Это, кстати, неправильно. Должен быть именно второй вариант, потому что со скобками — это таки вызов


LCR>>>1. Какой способ определения класса выбирают РСДН-гуру?


M>>Я не гуру , но использую 4-й способ Большниство всяких фреймворков, насколько знаю, используют его же


LCR>То есть можно не париться с чрезмерным расходом памяти. Спасибо, это хорошая новость


Ну, народ не парится, хотя должен был бы, имхо
... << RSDN@Home 1.2.0 alpha 4 rev. 1064>>


dmitriid.comGitHubLinkedIn
Re: Классы в Javascript
От: anonymous Россия http://denis.ibaev.name/
Дата: 10.04.08 10:31
Оценка: 13 (2)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Как я уже успел узнать, классы в js можно эмулировать кучей различных способов, один извращённее другого.

LCR>1.
LCR>[...]
LCR>И почему используется NewClass_method1() вместо NewClass_method1 в конструкторе?

Это ошибка.

LCR>2.

LCR>[...]
LCR>Уже лучше, но раздражает слово prototype. И имя класса каждый раз нужно снова повторять. И методы опять как-то нехорошо отделены от класса.

Этот способ считается классическим и самым правильным, но не позволяет создавать приватные члены.

LCR>3.

LCR>[...]

Впервые вижу.

LCR>4.

LCR>[...]
LCR>Самый чистый и опрятный вариант, но и тут оказываются грабли. Оказывается, мегадвижки не в состоянии соптимизировать код и прям-таки вынуждены плодить по новой функции на каждый экземпляр. Ужос, просто.

Зато тут можно за счёт замыканий создавать приватные члены.

LCR>В связи с этим у меня 4 вопроса:

LCR>1. Функции в javascript первоклассные или нет?

Да.

LCR>1. Какой способ определения класса выбирают РСДН-гуру?


4.

LCR>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2


http://dklab.ru/chicken/nablas/39.html
http://dklab.ru/chicken/nablas/40.html
Re[4]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 11:01
Оценка:
Mamut,

LCR>>По мне например, MyClass_method1() выглядит как вызов без аргументов.

M>Это, кстати, неправильно. Должен быть именно второй вариант, потому что со скобками — это таки вызов
Ага, разобрался.

LCR>>То есть можно не париться с чрезмерным расходом памяти. Спасибо, это хорошая новость

M>Ну, народ не парится, хотя должен был бы, имхо
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 11:01
Оценка:
anonymous,

LCR>>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2


A>http://dklab.ru/chicken/nablas/39.html

A>http://dklab.ru/chicken/nablas/40.html

Спасибо за ссылки.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Классы в Javascript
От: Панда Россия  
Дата: 10.04.08 11:27
Оценка: 12 (1)
LCR> this.method1 = function(x) {
LCR> alert("MyClass_method1");
LCR> }

LCR> this.method2 = function(x) {

LCR> alert("MyClass_method2");
LCR> }
LCR>}
LCR>[/code]
LCR>Самый чистый и опрятный вариант, но и тут оказываются грабли. Оказывается, мегадвижки не в состоянии соптимизировать код и прям-таки вынуждены плодить по новой функции на каждый экземпляр. Ужос, просто.

Я делаю так:

function MyClass()
{
   this.Define("method1", function(x) 
   {
    alert("MyClass_method1");
   })
}


А Define у меня пихает функцию в прототип объекта. Определен примерно так:

Object.prototype.Define = function(name, value)
{
  if (typeof(value) == "function" && !this.constructor.prototype[name])
  {
    this.constructor.prototype[name] = value;
  }
}




Хотя мне способ номер 2 тоже кажется нормальным. Меня слово prototype не раздражает. В моем способе каждый раз все равно плодится по новому экземпляру функции, но они сразу уничтожаются сборщиком мусора, и у всех объектов получается всего один экземпляр каждого метода, запихнутый в прототип.
Re: Классы в Javascript
От: DSD Россия http://911.ru/cv
Дата: 10.04.08 11:35
Оценка: 12 (1)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>1. Функции в javascript первоклассные или нет?

--

LCR>1. Какой способ определения класса выбирают РСДН-гуру?

способ 2.
что вам мешает взять правило: один класс=один js файл?
насчет prototype я бы не сказал, что это неудобно. наоборот — визуально сразу все понятно.
тем более можно без prototype объявить в том же модуле еще и вспомогательные функции, не требующие создания экземпляра класса, но так или иначе по смыслу к данному классу относящиеся:
function MyClass() {
  this.field1 = 666;
}
MyClass.prototype.method1 = function(x) {
    alert("MyClass_method1");
}
MyClass.prototype.method2 = function(x) {
  alert("MyClass_method2");
}

MyClass.UtilFunc1 = function(x) {
  return ...;
}

у меня таким образом много где используются подобные функции, например:
var str=String.sprintf('Hello %s, my dear %s!', 123, 'friend'); // Hello 123, my dear friend!
var str=String.Trim('   123   '); // 123
var str=String.AddChar('123','0',15); // 123000000000000
var str=String.AddCharL('123','0',15); // 000000000000123
var date_str=Date.formatDate(new Date(), 'W, D-M-Y H:I:S'); // Четверг, 10-04-2008 13:44:26
хотя при объявлении через прототип их можно было бы использовать так:
var str=('Hello %s, my dear %s!').sprintf(123, 'friend'); // Hello 123, my dear friend!
var str=('   123   ').Trim(); // 123
var str=('123').AddChar('0',15); // 123000000000000
var str=('123').AddCharL('0',15); // 000000000000123
var date_str=(new Date()).formatDate('W, D-M-Y H:I:S'); // Четверг, 10-04-2008 13:44:26
ну, тут уж кому как больше нравится.

Плюс за счет prototype реализуется наследование классов:
function MyChildClass(el) {
   this.set_element(el);
   this.items=new Array();
   this.tb=null;
   this.pad_left=0;
   this.cell_border=1;
   this.current_over_item=false;
   this.current_submenu=false;
   this.current_parent_menu=false;
}

MyChildClass.prototype=MyParentClass.prototype;

MyChildClass.prototype.method1 = function(x) {
    alert("MyChildClass method1");
}
где соответственно set_element — это метод предка MyParentClass.



LCR>2. Почему оптимизация в пункте 4 невозможна? Что мешает?

мешает то, что при создании большого количества объектов данного класса будут тормоза из-за создания множества анонимных функций для каждого метода.
дальше работать они будут практически с той же скоростью, как и созданные любым другим способом.
опять же проблемы с наследованием. частично они решаются через ж:
function MyParentClass(el) {
   this.set_element=function(el) {...};
}

function MyChildClass(el) {
   this.set_element(el);
}

MyChildClass.prototype=new MyParentClass;

MyChildClass.prototype.method1 = function(x) {
    alert("MyChildClass method1");
}
но это действительно решение через ж. да еще плюс создается лишний объект для "сдирания" с него прототипа(шаблона класса).

LCR>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2

скорость вызова — нинасколько. если и отличается, то на ничтожно малое время.
а вот скорость создания отличаться будет серьезно в случае this.method1=function(){...}.
--
DSD
Re: Классы в Javascript
От: _pk_sly  
Дата: 10.04.08 13:15
Оценка: 12 (1)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>1.

LCR>function MyClass() {
LCR> this.field1 = 666;
LCR> this.method1 = MyClass_method1();
LCR> this.method2 = MyClass_method2();
LCR> // ...
LCR>}

этот метод неверный, не нужны скобки.

LCR>4.

LCR>Самый чистый и опрятный вариант, но и тут оказываются грабли. Оказывается, мегадвижки не в состоянии соптимизировать код и прям-таки вынуждены плодить по новой функции на каждый экземпляр. Ужос, просто.

он не имеет права ничего оптимизировать потому что это — замыкания (closures), которые создаются каждый раз заново.

LCR>В связи с этим у меня 4 вопроса:


не забываем про способ JSON:

file.js
x = {
 a:5,
 f:function(x) { WSH.echo(x); },
 g:function() { WSH.echo("aaa"); }
};

x.f(100);
x.f(x.a);
x.g();
Re[2]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 13:43
Оценка:
DSD,

<useful comment skipped>

LCR>>2. Почему оптимизация в пункте 4 невозможна? Что мешает?

DSD>мешает то, что при создании большого количества объектов данного класса будут тормоза из-за создания множества анонимных функций для каждого метода.

Я имел ввиду что мешает не создавать множество одинаковых анонимных функций для каждого метода.

LCR>>3. Насколько скорость вызова метода определённого как MyClass.prototype.method1 отличается от метода, определённого как this.method2

DSD>скорость вызова — нинасколько. если и отличается, то на ничтожно малое время.
DSD>а вот скорость создания отличаться будет серьезно в случае this.method1=function(){...}.

опять возвращаемся к предыдущему вопросу...
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 10.04.08 13:43
Оценка:
_pk_sly,

LCR>>4.

LCR>>Самый чистый и опрятный вариант, но и тут оказываются грабли. Оказывается, мегадвижки не в состоянии соптимизировать код и прям-таки вынуждены плодить по новой функции на каждый экземпляр. Ужос, просто.

__>он не имеет права ничего оптимизировать потому что это — замыкания (closures), которые создаются каждый раз заново.


гхм. Ну что мешает замыкания создавать каждый раз не заново?

LCR>>В связи с этим у меня 4 вопроса:


__>не забываем про способ JSON:


__>file.js

__>
__>x = {
__> a:5,
__> f:function(x) { WSH.echo(x); },
__> g:function() { WSH.echo("aaa"); }
__>};

__>x.f(100);
__>x.f(x.a);
__>x.g();
__>


Э... а где тут класс?
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[3]: Классы в Javascript
От: _pk_sly  
Дата: 10.04.08 14:03
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>_pk_sly,


__>>не забываем про способ JSON:


__>>file.js

__>>
__>>x = {
__>> a:5,
__>> f:function(x) { WSH.echo(x); },
__>> g:function() { WSH.echo("aaa"); }
__>>};

__>>x.f(100);
__>>x.f(x.a);
__>>x.g();
__>>


LCR>Э... а где тут класс?


класса нет, но есть объект со свойствами и методами.

так же, как и в твоём примере №1

если хочешь "конструктор" верни эту штуку из функции
Re[3]: Классы в Javascript
От: anonymous Россия http://denis.ibaev.name/
Дата: 10.04.08 14:20
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

__>>он не имеет права ничего оптимизировать потому что это — замыкания (closures), которые создаются каждый раз заново.

LCR>гхм. Ну что мешает замыкания создавать каждый раз не заново?

Контекст мог измениться. Если не пересоздать замыкание, оно будет со старым контекстом.

LCR>Э... а где тут класс?


Эго тут нет, вероятно, это не твой случай.
Re[3]: Классы в Javascript
От: Панда Россия  
Дата: 10.04.08 14:47
Оценка:
LCR>гхм. Ну что мешает замыкания создавать каждый раз не заново?

Потому что они все разные.
Re[4]: Классы в Javascript
От: Панда Россия  
Дата: 10.04.08 14:51
Оценка:
__>если хочешь "конструктор" верни эту штуку из функции

И получаем ту же проблему, что в варианте 4. Ничем не лучше, чем, собственно, вариант 4.
Re[5]: Классы в Javascript
От: Панда Россия  
Дата: 10.04.08 14:58
Оценка:
П>И получаем ту же проблему, что в варианте 4. Ничем не лучше, чем, собственно, вариант 4.

Даже хуже, чем вариант 4, потому что полученные объекты не будут иметь отдельного, характерного только для них, общего прототипа — их прототип будет прототипом Object. Вопрос-то был не в том, как бы похитрее создать единичный объект, а как создать класс и потом наплодить однотипных объектов, не плодя идентичных функций.
Re: Классы в Javascript
От: . Великобритания  
Дата: 10.04.08 15:22
Оценка: 12 (1)
Lazy Cjow Rhrr wrote:

такое ещё не упомянули
> 2.
function MyClass() {
   this.field1 = 666;
}
MyClass.prototype = {
  method1: function(x) {
    alert("MyClass_method1");
  },
  method2: function(x) {
   alert("MyClass_method2");
  }
}

А вообще, стоит осознать простую мысль — в яваскрипте нет классов, всё — объекты и язык не ОО в классическом понимании. Даже функции — объекты. А метод — это обычная функция, просто если функцию вызвать вот таким способом obj.meth() внутри неё значению this будет присвоен obj.
Соответственно и дизайнить программу по другому можно.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Классы в Javascript
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.04.08 03:44
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>Как я уже успел узнать, классы в js можно эмулировать кучей различных способов, один извращённее другого.
Я вот не уверен, что классы в джаваскрипт вообще нужны. Совершенно непонятно, зачем что-то эмулировать. Как правило, это всего лишь отражение дурной привычки к одному языку программирования. Имхо, лучше изучить натуральные для JS методики программирования.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Классы в Javascript
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 11.04.08 03:46
Оценка:
The Dot,

<code>
Спасибо, теперь есть из чего выбрать

.>А вообще, стоит осознать простую мысль — в яваскрипте нет классов, всё — объекты и язык не ОО в классическом понимании.


Ну это как раз понятно. Я ведь в первом посте и сказал про эмуляцию классов, а не про определение классов. Динамическое изменение сигнатуры объекта как раз должно мне пригодиться...
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.