Pull to refresh
1
0
Dmitry Soshnikov @dsCode

User

Send message
> Я для себя ищу ответ на вопрос.

Вы выбрали неудачную позицию — не анализирующую со стороны, а отстаивающую JS. Смотрите профессиональней, оценивайте, видьте плюсы и минусы. JS написали не Вы, а B. Eich, который заимстовал идеи ещё у кого-то. Он (B. Eich) может, ещё и может холиворить с Guido Van Rossum-ом =) но, уж явно не будет этого делать ;)
> Корректно, например Ruby с Python или JS с Io

Почему? Потому что там терминология «класс», а там — «прототип»? Это не существенно. Важным атрибутами для анализа являются «динамика vs. статика» + механизм разрешения характеристик объектов. В Python и JS — они практически идентичны.

> но сами же указываете в статье их различия

Я-то указвыаю. Просто вы сказали, что «не очень корректно сравнивать», думал, тоже укажете на какую-то информацию и внесёте ясность. Ну, да ладно.
> Не похожее на обычную парадигму.

Какую ещё обычную?

> Понятия «нормальное» наследования не существует. В реализации JS есть свои плюсы и минусы

Так в том-то и дело, что JS полностью и насквозь пронизан наследованием ещё до того, как мы напишем сколь-нибудь серьёзные объекты.

alert(1..toString());

Как только вы полностью поймёте эту строку, вопрос о наследовании отпадёт сам собой. И вы увидите, что наследование в JS мало чем отличается от наследования в Python.
Зрите в корень. У JS сейчас ниша занята определённая. При преносе этой нише в то же русло, что и Ruby — дополнительный функционал (соекты, файлы, многопточность и т.д.) допишутся в движок очень быстро. Более того, многие реализации этот функционал имеют (скачайте и скомпиллируйте, например, SpiderMonkey с поддержкой объекта File и ещё много чем).

> — ООП ужасно неудобное

Альтернативная парадигма. Скорее, Вам, «ужасно непривычная».

> При создании экземпляров копируются методы и свойства, что сильно засоряет память и бьёт по производительности

Не возражаете, если я назову это бредом? ;)

— изначально нет никакой найтивной поддержки модульности и нормального наследования, что вполне объясняется предназначением языка — «небольшие скрипты улучшения интерфейса на клиентской стороне»

Тоже, не против, если назову это ерундой? ;)
> Да, примеси не являются большим отличием Ruby

Являются-являются. В Ruby — подмешивание (ссылки на модули, к которым происходит делегация — поменяйте в рантайме значение в модуле, и оно тут же отобразится на всех объектах, которые подмешали эту примесь), в JS — расширение и один прототип для делегации (но, к слову сказать, в некоторых реализациях можно задействовать __noSuchMethod__ и делегировать по альтернативным цепям прототипов, т.е., по сути, организовывать множественное наследование или подмешивание).
> На мой взгляд это без труда обходится с помощью прототипов.

А в JS в качестве прототипа может быть указан лишь один объект (в отличии, скажем, от языка Self, от которого JS также вобрал немало идей). Примиси же, в одной из своих особенностей, позиционируются как альтернатива множественному наследованию, т.е. объект может подмешать несколько объектов и делегировать к ним. И, повторю, подмешивание и расширение — это разные вещи. Подмешивая, мы, по сути, создаём ещё один прототип для делегации, а расширяя — просто копируем свойства в объект. Почитайте ещё раз ссылку, которую я давал в предыдущем посте.

> Можете привести «живой» пример примеси?

class Age
    include Comparable
 
    attr_accessor(:age)
 
    def <=>(cmp)
        @age <=> cmp.age
    end
end

a, b = Age.new, Age.new
a.age = 10
b.age = 11
a < b # true

Данная примесь, кстати, больше относится к штриху.

А Вас что именно интересует? Давайте и Вы пример приведите.

> А чем это плохо? Что ссылки вида «this.» отъезжают?

При чём здесь плохо? В Ruby — всего лишь — своя реализация. В JS — всего лишь своя реализация. Ни больше, ни меньше.

> Вот я и пытался выявить что-то эдакое, чего Javascript не сможет ну никак выжать.

Если видите большой смысл — почему бы не повыяснять? А вообще, тогда надо было спрашивать, «вот чего такого нет в Python-e или Self, или SmallTlak, или… (возьмите любой язык, от которого JS питал идеи), чего надо было делать в JS?». Ответы, кстати, найдёте, поскольку JS базируясь на определённых идеях, вносил и свои особенности. Так же и другие языки.
> То бишь JS их особо не отличает от других объектов, поэтому и не содержит большого числа специальных конструкций

Строки в JS — это примитивный тип. Объектный тип — только один — Object (не путать с конструктором Object!). Встроенный же конструктор String, создаёт объект типа Object, ставит его внутреннее свойство [[Class]] в «String» и записывает во внутреннее свойство [[value]] соответствующее примитивное значение, т.е. строку.
> Насчет примесей, все-таки прототипы и классы не очень корректно сравнивать.

Да, я знаю, что такое класс, и что такое прототип. Опять же, писал и разбирал это подробно в статье об ООП в JS. Почитайте, особенно раздел о динамично-классовой организации.

А что значит не «очень корректно»? А как «очень корректно» будет? Расскажите, интересно.

> Извеняюсь за занудство:) Ни неразу не встечал «hidden». SingletonClass или MetaClass.

Да, в Ruby принята эта терминология, для объектов создаётся SingletonClass, для классов — MetaClass. Однако, обе эти сущности являются терминологическим подмножеством VirtualHiddenClass. При этом, терминология MetaClass, применённая в Ruby, может сбить с толку в классическом понимании этого термина. Хотя, как часть — класс содержащий методы другого класса — можно назвать и метаклассом, как это сделано в Ruby.
Да забей, всё норм ;)
> Кхм. А чего из этого нет в Javascript?

> «примеси»

Примесей, в понимании Ruby, в JS нет; ECMA-262-3 понятия «примесь» не описывает. Расширение объектов, как имитация, является имитацией, поскольку в Ruby, создаётся ссылка на модуль, а не просто копируются все свойство в расширяемый объект. Вот здесь немного писал об этом.

> замыкания с полной привязкой к переменным

В JS this не замыкается, а определяется динамически выражением вызова при входе в контекст. В Ruby self замыкается.

> В Ruby… можно добавлять методы не только в любые классы, но и в любые объекты

Кстати, не совсем верно, относительно Ruby. Там создаётся hidden-класс для каждого объекта, который и хранит методы. В JS — объекты полностью изменяемы (mutable) и могут сами хранить методы.

> покажите мне как сделать eval()

eval — вообще основная функция (всех) скриптовых языков.

> Есть ли там null, обладающий особыми свойствами?

А что за особые свойства? null-ы, nil-ы, None-ы есть во многих языках.

> Могу ли я работать с переданными аргументами любой функции как с массивом arguments?

Да, выше уже был пример на Python-e. Однако, в отличии от JS, можно анализировать не только позиционные аргументы, но и именованные:

def a(*args, **kwargs):
  print(args, kwargs)

a(10, 20, b=30, c=40)


В Ruby тоже свободно:

def a(*args)
  p args
end

a 1, 2, 3 # [1, 2, 3]


> Могу ли я создать в них объект с данными и методами, написав:

Да, в Python, можно даже использовать для этого литерал словаря (не создавая отдельный класс) — явное сходство с объектами в JS:

obj = {
  'a': 10,
  'b': 20,
  'method': lambda x: x + 10
}

obj['method'](10) # 20

> Есть Javascript. Зачем нужны другие скриптовые языки?

Время никого и ничего не щадит. Это как, если бы сказали в советские времена: «Да-а, какой шикарный автомобиль — Москвич 412! Лучше уже вряд ли что-нибудь придумают!» Какие-то новые идеи, архитектурные решения и т.д. появляются в процессе эволюции и развития. Мы можем лишь анализировать их, находить достоинства и недостатки, создавать собственные языки.

ECMAscript, кстати, очень много идей позаимствовал из Python-a. Они очень схожи в идеологии, опять же, в статье об ООП в JS, писал об этом.
> Javascript исполняется на клиенте, а руби на сервере

Среда и место исполнения — это мелочи, следствие.

> вообще не понимаю, как Вы можете сравнивать Javascript и Ruby

А что непонятного? Сравниваются сами языки. Кстати, JS, Python и Ruby стоят в одной линейке, у них схожие идеологии.
> В начале всех начал был ассемблер

Ну, здрасте! ;) Язык ассемблера — это супер-мега абстракция (относительный сверхвысокий уровень), по сравнению с тем, что «было в начале».
Narcissus ;) Тоже, кстати, B. Eich написал.
> Вы, что ли, не читаете, когда ответ пишете; мне непонятно.

a?

> Я же не спрашиваю

ну, тогда можете проигнорировать мой ответ. Я отметил абстрактно.

> Я указываю

да что Вы? ;)

> на то, что более-менее крупный json читается человеком гораздо сложнее, чем аналогичный xml; на это и указал.

локальная привычка, не более; как вариант, повторю, посмотрите в сторону YAML, тот ещё легче читается.
> Что-то вы тут перебрали :) Xml читается куда легче, чем json, даже при наличии <>

Вопрос привычки. XML в отличии от JSON перегружен ненужными скобками, атрибутами с кавычками, знакми «равно» и т.д. Хотя, парсер для XML-подобных языков писать легче, он стандартизован и один на всех.

JSON — легче по трафику для передачи.

Также, есть ещё YAML, который ещё легче JSON-a.
Спасибо, интересно.

У меня коллега на работе, в качестве кандидатской писал нечто подобное. Только у него строилась матрица вероятностей нот. У него нет аккаунта на Хабре, но он сейчас посмотрел Ваш код и проект и сказал, что плюсом у Вас является анализ в дереве предыдущих нот, тогда как у него — следующая нота строится лишь в зависимости от текущей, но, зато, у него учитывается вероятности ноты появления ноты в оригинальном произведении (не просто рандомом берётся). Если вдруг заинтересуетесь, могу скинуть его аську.
> номер машины в виде штрих кода быстро был распознан сканером и ворота незамедлительно ушли под землю

Не практично, архитекторы бы не стали делать систему с уходом под землю и обратным подъёмом из-под земли — а вдруг, система заклинит, когда машина будет проезжать по ним, и ворота (глюком) выйдут из-под земли в этот момент? Наверное, ворота, всё же, раскрывались/закрывались, что, в случае аварии, более безопасно.

Автопилот, новости на бортовом компьютере и «зелёный сектор» (не важно чего, в данном случае, новостей) — было неоднократно и, да, ассоциируется с будущим.

Продолжайте, интересно ;)
Ага, пожалуй. Только этот private тоже до конца не скрыт (в некоторых реализациях можно свободно менять var-ы из замкнутого контекста). Вот здесь немного писал об этом.
И в итоге counter, равно как и .increment будет у каждого свой, это уж точно не «статическая переменная».
> зачем свойство? просто переменная, доступная методам через замыкание, в котором сохранен контекст функции-конструктора.

Я просто подумал, что вы говорите про:

function A() {}
A.staticProperty = 10;

а не про:

function A() {
  var counter = 0;
  return function() {
    alert(++counter);
  };
}

Кстати, этот второй случай — лишь создание внутреннего замыкания; в качестве же конструктора такую функцию уже не использовать (т.к возвращается не объект и не this, а функция), поэтому, это вряд ли может подойти под определение static в плане расшаривания свойств между экземплярами конструктора. Да, переменная counter будет шарится между вызовами замкнутой анонимной функции (через [[Scope]]), но только это не относится к созданию экземпляров и расшаренного между ними («статического») свойства.

Если в качестве конструктора использовать эту возвращённую функцию — то тоже смысла мало, counter будет доступен только в пределах этого анонимного конструктора.

Ещё можно такой вариант использовать — хранить не в самом прототипе, в скопе обрамляющей функции при описании прототипа. Получится, что переменная также расшарена между всеми экзеплярами, но ещё и недоступна снаружи:

function A() {} // конструктор

A.prototype = (function () { // обрамляющий контекст

  // расшаренное "статическое" свойство
  var sharedProperty = 10;

  // сам прототип
  return {

    constructor: A,

    getSharedProperty: function () {
      return sharedProperty;
    },

    setSharedProperty: function (newValue) {
      sharedProperty = newValue;
    }
  };
})();

var a = new A;
var b = new A;

alert(a.getSharedProperty()); // 10
alert(b.getSharedProperty()); // 10

b.setSharedProperty(20);

alert(a.getSharedProperty()); // 20
alert(b.getSharedProperty()); // 20

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity