LINUX.ORG.RU

почему в JS принят такой стиль?

 ,


0

1

Я про классы. Когда мы пишем, например,

MyClass=function(){}
MyClass.prototype=someObject

следует, наверное, понимать, что классом тут является не MyClass, а MyClass.prototype, а MyClass является всего лишь конструктором, с опциональной инициализацией.

Соответственно, мы с тем же успехом можем писать

MyClass={
 create: function(){return Object.create(this)},
 //enother fields here
}
ну и в create мы можем опционально также инициализировать поля.

На мой взгляд, из-за этого дерьма происходит много путаницы. Многоие разработчики вообще тупо путают классы с конструкторами, да и собственно, кто сказал, что засирать без надобности глобальное пространство имен есть гуд?

Кроме всего прочего, во втором варианте код всегда лаконичней и ясней.

Почему массово принято это извращение? Это связано с оптимизацией, или что?



Последнее исправление: javaQest (всего исправлений: 3)
Ответ на: комментарий от anonymous

Композиция == пайп из bash, записанный задом наперёд.

Оно сильно полезно, когда хочешь обработать данные из promise, поскольку есть pipeP и composeP. Разница всё та же: pipe == compose с аргументами в обратном порядке.

x3al ★★★★★
()
Ответ на: комментарий от anonymous

При том, что если можешь ООП, такое говно НИКОГДА, не придется пейсать.

javaQest
() автор топика
Ответ на: комментарий от x3al

Оно сильно полезно, когда хочешь обработать данные из promise

Я не говорю что оно вообще не нужно. Просто наворачивать какулы на каждый чих это нездоровая тема. Ты вот можешь сказать что делает вышеприведенный код?))

anonymous
()

Ты хоть один малюсенький проект довел до коммерческого успеха или только тут изливаешь свой завышенный интеллект?

anonymous
()
Ответ на: комментарий от javaQest

Во-первых, не трогай кошек. grep сам так умеет.

Во-вторых,

R.compose(X.grep('foo'), X.cat)
, можно тут же применить на file:
R.compose(X.grep('foo'), X.cat)(file)
, предполагая, что X — это нечто, дающее выполнить башекоманду.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от x3al

ну и зачем писать кучу лапши, там где все просто как 3 копейки?

javaQest
() автор топика
Ответ на: комментарий от javaQest

И .filter ты будешь внутри каждого объекта реализовывать? Или таки сделаешь fmap и представишь, что Tasks — это монада, куда можно поднять filter?

x3al ★★★★★
()
Ответ на: комментарий от x3al

Покажи, как ты офигенно чисто, ООПшно и императивно повторишь http://fr.umio.us/why-ramda/

Но зачем? Простые циклы по месту решают большинство проблем. Библиотка highorder domain specific functions? Не смеши, такие же изолированые использования, до DRY как до бреста раком.

anonymous
()
Ответ на: комментарий от x3al

Там, кстати, еше красивей можно засазарить

tasks.incompleted
безо всякого фильтра.

javaQest
() автор топика
Ответ на: комментарий от javaQest

У тебя есть, скажем, 2 класса: Tasks и People. Один из них подкласс другого? Или у тебя mixin (которые ты не любишь) с .filter (как это будет выглядеть?)?

Когда достаточно близких к функторам классов станет порядка пары десятков, у тебя появится fmap.

Нет, конечно, если Tasks предоставлен твоим фреймворком и ты ни одного собственного класса не пишешь — тогда ок.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от javaQest

Класс не перестает быть классом, от того что нет сахара для его определения

Ну ок, ассемблер - ООП с классами.

ya-betmen ★★★★★
()
Ответ на: комментарий от x3al
Tasks={
 create: function(){
  var o = Object.create(this)
  o.tasks=[]
  return o
 },
 add: function(person){
  this.tasks.push(person)
 },
 filter: function(value){
   return this.tasks.filter(function(person){return person.task.status==value})
 }
}

Task={
 status: "incomplete",
 on: function(){this.status="complete"},
 create: function(task){
   var o=Object.create(this)
   o.task=task
   o.task.then(function(){o.on()})
   return o
 }
}

People={
 create: function(name){
  var o=Object.create(this)
  o.name=name
  return o
 },
 addTask: function(task){
  this.task=task
 } 
}

setPromise=function(timeout){return new Promise(function(resolve, reject){
  setTimeout(function(){resolve(1)}, timeout)
})}

person1=People.create("John")
person2=People.create("Jack")
person3=People.create("Jain")

person1.addTask(Task.create(setPromise(1000)))
person2.addTask(Task.create(setPromise(2000)))
person3.addTask(Task.create(setPromise(3000)))


tasks=Tasks.create()
tasks.add(person1)
tasks.add(person2)
tasks.add(person3)

check=function(timeout){
 setTimeout(function(){
  console.log(tasks.filter("incomplete"))
  console.log(tasks.filter("complete"))
  console.log("\n\n")
 }, timeout)
}
 
check(1000)
check(1500)
check(2000)
check(2500)
check(3000) 
check(3500) 

out

[ { name: 'Jack', task: { task: {} } },
  { name: 'Jain', task: { task: {} } } ]
[ { name: 'John', task: { task: {}, status: 'complete' } } ]



[ { name: 'Jack', task: { task: {} } },
  { name: 'Jain', task: { task: {} } } ]
[ { name: 'John', task: { task: {}, status: 'complete' } } ]



[ { name: 'Jain', task: { task: {} } } ]
[ { name: 'John', task: { task: {}, status: 'complete' } },
  { name: 'Jack', task: { task: {}, status: 'complete' } } ]



[ { name: 'Jain', task: { task: {} } } ]
[ { name: 'John', task: { task: {}, status: 'complete' } },
  { name: 'Jack', task: { task: {}, status: 'complete' } } ]



[]
[ { name: 'John', task: { task: {}, status: 'complete' } },
  { name: 'Jack', task: { task: {}, status: 'complete' } },
  { name: 'Jain', task: { task: {}, status: 'complete' } } ]



[]
[ { name: 'John', task: { task: {}, status: 'complete' } },
  { name: 'Jack', task: { task: {}, status: 'complete' } },
  { name: 'Jain', task: { task: {}, status: 'complete' } } ]


javaQest
() автор топика
Ответ на: комментарий от x3al

Хотя, класс people — это уже твоя отсебятина, он к вопросу непосредственного отношения не имеет. Без него — проще.

javaQest
() автор топика
Ответ на: комментарий от jtootf

А че это вообще такое, изоморфмный? Если простым человеческим языком? Вот, например, кошечка изоморфна собачке?

javaQest
() автор топика
Ответ на: комментарий от mix_mix

Ну, я не знаю, конечно, мат смысл этого слова, математики, обычно, делают простые вещи сложными, но если брать этимологию

Происходит от др.-греч. ί̓σος «равный, одинаковый, подобный» + μορφή «вид, наружность, форма».

и от нее плясать, то они таки, изоморфны:)

javaQest
() автор топика
Ответ на: комментарий от javaQest

Эмм. Твой код не-френдли к plain old javascript objects, он что, рассчитан, что данные самозарождаются в жабоскрипте?

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

 addTask: function(task){
  this.task=task
 } 
не будет работать даже в теории, если соотношение people-tasks не 1:1. Если, конечно, ты не хочешь сойти с ума, копируя референсы на task'и пять тысяч раз по разным массивам.

Tasks

у тебя — бесполезный контейнер, нужный исключительно ради идиотского сахара над filter, заточенного на 1 юзкейс.

И да, ты когда-нибудь слышал о loose coupling?

    var incomplete = R.filter(R.where({complete: false}));
    var sortByDate = R.sortBy(R.prop('dueDate'));
    var sortByDateDescend = R.compose(R.reverse, sortByDate);
    var importantFields = R.project(['title', 'dueDate']);
    var groupByUser = R.partition(R.prop('username'));
    var activeByUser = R.compose(groupByUser, incomplete);
    var gloss = R.compose(importantFields, R.take(5), sortByDateDescend);
    var topData = R.compose(gloss, incomplete);
    var topDataAllUsers = R.compose(R.mapObj(gloss), activeByUser);
    var byUser = R.use(R.filter).over(R.propEq("username"));

Это — все фильтры, которые юзал оригинал, чтобы превратить массив данных (в формате, ожидаемом от бэкэнда), в удобоваримую форму. А у тебя что? Бесполезная игрушка для бесполезного сахара, которая нерасширяема в принципе. Которую руками привязывать к исходным данным. В твоём стиле реализовать все эти фильтры займёт строк 700 минимум и это будет медленно.

Зато ООП, млин. Обернул страшный filter в обёртку, умеющую ровно 1 юзкейс.

check(1000)
check(1500)
check(2000)
check(2500)
check(3000) 
check(3500) 

Пожалуйста, скажи, что ближе к продакшну ты пользуешь хотя бы map. Или это слишком функционально и нафиг не нужно в Ъ-ООП языке?

x3al ★★★★★
()
Ответ на: комментарий от javaQest

Окей, как ты фильтруешь по нескольким параметрам? Делаешь .filterByPerson, .filterByDate, .filterByDateAndPerson, .filterByStatus, .filterByPersonAndStatus и ради удобства — .completed и .completedByPerson?

x3al ★★★★★
()

но в оригинале у человека могло быть несколько задач, а не одна. что мешает создать массив tasks?
слышал о loose coupling?

Не слышал, но стиль который ты показываешь, мне не нравиться. Такое обычно используется хипстерочками, чтобы никто не понял, что код — говно. Типо, поди разберись, в этом синтаксическом поносе, проще на слово поверить, что там все ок.

Бесполезная игрушка для бесполезного сахара, которая нерасширяема в принципе.

С чего ты взял, что она не расширяема? Тут конечно, надо сделать скидку на то, что это писалось не под реальную задачу, а под коней, но в целом, ооп, оно на то и ооп, чтобы быть экстремально гибким, и расширяемым.

Пожалуйста, скажи, что ближе к продакшну ты пользуешь хотя бы map. Или это слишком функционально и нафиг не нужно в Ъ-ООП языке?

я специально не стал усложнять, map в данном случае сильно код не сократил бы, а так проще распарсить. А вообще map b ghjxbt редьюсы никакого отношения к ФП не имеют, это просто функции. С такими понтами можно дойти до того, что использование ф-ций как таковое — это ФП-стайл. Я ничего против map не имею, в целом.

javaQest
() автор топика
Ответ на: комментарий от x3al

Хотя я вообще имел в виду другое: класс People, ничерта не связанный с Tasks. С ООП-подходом по методу анонiмуса у People и Tasks — отдельные .filter, отличающиеся... ничем. Без него — filter один и снаружи.

x3al ★★★★★
()
Ответ на: комментарий от javaQest

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

что мешает создать массив tasks?

//fixed

javaQest
() автор топика
Ответ на: комментарий от javaQest

Тут конечно, надо сделать скидку на то, что это писалось не под реальную задачу, а под коней,

Ты превращаешь flat-структуру в nested ради одного сраного фильтра. Когда у тебя появляется второй параметр, по которому нужно фильтровать — расширяемость заканчивается и мы понимаем, что архитектура говно.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Я имел в виду, что для демонстрации самого принципа, достаточно было 2-х классов, Task и Tasks. Но, не важно, проехали.

javaQest
() автор топика
Ответ на: комментарий от x3al

А что мешает сделать отдельный фильтр по двум параметрам? Для этого достаточно добавить один метод в класс. Или заменить. Наоборот это говорит о хорошей расширяемости.

javaQest
() автор топика
Ответ на: комментарий от x3al

не сплясав вокруг этих людей.

и что? ты хочешь вобще код не писать, чтобы все само по себе проектировалось? так не бывает. Уже видно, что ты просто откровенно придираешься. Прекрати:)

javaQest
() автор топика
Ответ на: комментарий от x3al

Хотя я вообще имел в виду другое: класс People, ничерта не связанный с Tasks. С ООП-подходом по методу анонiмуса у People и Tasks — отдельные .filter, отличающиеся... ничем. Без него — filter один и снаружи.

Я ведь уже 3 раз повторяю, что фильтр там один.

javaQest
() автор топика
Ответ на: комментарий от javaQest

А что мешает сделать отдельный фильтр по двум параметрам? Для этого достаточно добавить один метод в класс. Или заменить. Наоборот это говорит о хорошей расширяемости.

Есть R.filter по ∞ параметрам. Есть Array.prototype.filter, в конце концов. Но нет, нужно велосипедить бесполезный фильтр в каждом классе.

x3al ★★★★★
()
Ответ на: комментарий от javaQest

На самом деле, я там чушь написал. Диффеоморфизм и есть изоморфизм в категории гладких многообразий. Кошечку и собачку гладкими считать нельзя, банально потому, что они состоят из конечного числа атомов. Учитывая, что это число различно, никакого изоморфизма так же не построить. Но это если мыслить в терминах Set, а нам, в принципе, никто не мешает свою категорию сконструировать.

mix_mix ★★★★★
()
Ответ на: комментарий от javaQest

Уже видно, что ты просто откровенно придираешься.

Чуть выше я давал линк, где 1 массив POJO сортируется, группируется и фильтруется без единого класса. С твоим подходом каждая операция — отдельный метод класса, причём на каждый чих эти методы надо перекраивать и добавлять.

x3al ★★★★★
()
Ответ на: комментарий от x3al

кстати, про map. Все эти мапы гораздо органичней выглядят в ооп, нежели в ФП. Особенно в динамике. Например на Io это вот так примерно выглядит

list(something) filter(> 3) reduce(* 5)

javaQest
() автор топика
Ответ на: комментарий от x3al

Но нет, нужно велосипедить бесполезный фильтр в каждом классе.

ок, я 4-й раз повторю, там нет отдельного фильтра в каждом классе.

javaQest
() автор топика
Ответ на: комментарий от x3al

каждая операция — отдельный метод класса,

про наследование мы значит, не слышали. Это в ФП, как раз с этим проблемы.

javaQest
() автор топика
Ответ на: комментарий от x3al

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

бесполезный — не надо. А полезный — надо. Это полиморфизм, кагбе.

javaQest
() автор топика
Ответ на: комментарий от javaQest

ок, я 4-й раз повторю, там нет отдельного фильтра в каждом классе.

Ты не можешь фильтровать список юзеров. Вейт, у тебя его нет. Окей.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Ты не можешь фильтровать список юзеров. Вейт, у тебя его нет. Окей.

Нет, в данном случае, мы фильтруем как раз юзеров, по таскам. Можно было фильтровать одни таски, можно и то и другое, это по желанию.

javaQest
() автор топика
Ответ на: комментарий от x3al

Да, я там назвал неудачно

o.tasks=[]

правильней было users = [],

поспешил, извиняюсь. Все правильно, там список юзверей а не тасков:)

javaQest
() автор топика
Ответ на: комментарий от loyd

Нулевой объект имеет тип «объект».

OK, но причем тут null?

js> typeof []
"object"
js> [] instanceof Object
true
js> typeof null
"object"
js> null instanceof Object
false

Без комментариев.

dexpl ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.