«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2018/10/02 10:19:00  №1273289 1
Что за наркоман выдумывал принцип работы объектов в JS? Поскорее бы вернуться к PHP, там все намного логичней.
Ответы: >>1273430 >>1273613
Аноним 2018/10/02 13:20:45  №1273430 2
>>1273289

Вообще, там была идея сделать объекты без классов, на прототипах. Вот тут вот https://medium.com/@benastontweet/lesson-1a-the-history-of-javascript-8c1ce3bffb17 пишут, что автор вдохновлялся языками Java, Scheme и Self (можешь почитать про последние 2 для расширения кругозора).

В традиционном ООП мы описываем класс с полями и методами, при желании наследуем классы, а затем создаем объекты этих классов. В прототипном подходе классы выкидывают как ненужную сущность и объекты создают из других объектов с помощью "наследования" через прототипы.

Класс с полями и методами из традиционного ООП в прототипном заменен на базовый объект с методами. Операции наследования классов и создания объекта класса в прототипном ООП заменены на одну операцию создания нового объекта.

То есть мы создаем "базовый" объект такого вида:

var basePerson = {
setSalary: function (s) { this.salary = s; },
getSalary: function() { return this.salary; },
getName: function() { return this.name; }
};

А затем от него создаем (наследуем) уже конкретные объекты:

var ivan = Object.create(basePerson, { name: "Ivan", salary: 100 });
var peter = Object.create(basePerson, { name: "Peter", salary: 200 });
console.log(peter.getName());

Object.create() создает новый объект с указанным прототипом и свойствами.

Для удобства, можно добавить функцию-конструктор для создания объектов:

functon newPerson(name, salary) {
return Object.create(basePerson, { name: name, salary: salary });
}

var sidor = newPerson('Sidor', 300);

Как видишь, это похоже на традиционный ООП, где классы сделаны в виде объектов.

Наследование базовых объектов делается аналогично созданию:

var baseManager = Object.create(basePerson, {
getSubordinates: function () { ... },
setSubordinates: function () { ... }
});

var fedor = Object.create(baseManager, { ... });

Правда, в первоначальных версиях ES3 почему-то не сделали Object.create(), а заставили создавать объекты только через конструкторы:

// Код, что и выше, но в версии для ES3
function Person(name, salary) {
this.name = name;
this.salary = salary;
}

Person.prototype = basePerson;
var sidor = new Person('Sidor', 300);

Из-за отсутствия Object.create() наследование базовых объектов в ES3 делается очень коряво и я не рискну написать его по памяти.

В таком подходе есть и плюсы - например, здесь базовый объект можно передавать в функцию (в PHP класс нельзя передать или сохранить в переменную, только имя класса). В некоторых ООП-языках, впрочем, для классов есть представляющие их объекты:

- в Яве: https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
- в Руби: https://ruby-doc.org/core-2.5.1/Class.html

Ну и в общем прототипный ООП как-то не очень нашел поддержку и люди начали писать библиотеки для имитации традиционного ООП на классах. А в ES6 завезли синтаксис для описания классов, правда самих классов фактически по прежнему нет.
Ответы: >>1273495
Аноним 2018/10/02 15:29:51  №1273495 3
>>1273430
Вывод один - надо забивать на глубокое изучение JS и учить jquery.
Ответы: >>1273613
Аноним 2018/10/02 19:09:48  №1273613 4
>>1273289>>1273495

В js есть только объекты. Больше ничего.
Есть еще примитивы, но их можно тоже рассматривать в качестве синглтон объектов, потому как они боксятся, а сделаны разумеется для производительности. (тем более что сейчас ничего не мешает у примитивных добавить в цепочку прототипов прокси объект, отлавливащий сообщения, типа присваивания, и реалиховать поведение прототипов как полноценных объектов, но это ни к чему. проще воспринимать их как синглтоны. когда надо, любой примитив можно обернуть в полноценный независимый объект).

Так. Короче только объекты.
Все объекты делятся на callable и non-callable. Callable это функции, в понимании большинства. Но по факту это все те же объекты, со всеми свойствами что и у других.

Все объекты могут принимать всего несколько типов сообщений - get, set и call. При чем call может принимать только callable объект. при попытке послать call сообщение не-callable объекту будет исключение.

Сообщение get содержит один параметр, сообщение set два. Сообщение call параметром содержит кортеж аргументов, а так контекст this.

Если в объекте (а так же в цепочке прототипов) не назначены слушатели для get и set с определенными параметрами, ищутся слоты с такими именами в объекте и по цепочке. Если находится возвращается то, что в них лежит. Если в них лежит callable объект и ему посылают сообщние call сразу как получили его из слота, то у него будет перегружен контекст (this) на объект из чьего слота его получили. Если только этот объект не был сконструирован стрелочным синтаксисом, иначе контекст перегрузить нельзя. Если после получение callable объекта из слота его сразу не вызвать, а например положить ссылку на него в переменную, то контекст будет сброшен на тот, который был установлен у него в момент его создания (и это не обязательно будет тот же объект из чьего слота его получили).

У callable объектов есть scope (область видимости) и контекст (this) в момент посылки им сообщения call (вызова). scope средствами языка перегрузить нельзя (на самом деле частично можно изъебнуться с помощью eval), но некоторые окружения позволяют (например в ноде есть модеуль vm), this перегружается у callable объектов сконструированных не-стрелочным синтаксисом

Классов нет. Есть конструкторы. Любой конструктор принимает новый созданный объект, которому выставлен определенный прототип (другой объект). Оператор instanceof (someObject instanceof SomeClassName) проверяет лишь есть ли в цепочке прототипов у someObject объект который лежит у SomeClassConstructor в слоте с именем prototype. На сам конструктор ему поебать. Чтобы сменить класс, достаточно сменить цепочку прототипов. Даже если объект был сконструированным определенным конструктором.

Так же у объектов есть параметр ограничения доступа, контролирующие его расширяемость или изменяемость (sealed, extensible, frozen). У слотов объекта есть параметры configurable, enumerable, writable. Параметры слотов объекта не влияют на объекты, что в них лежат. Они лишь контролируют доступ к самим слотам.

Все. Никаких классов. Никаких интерфейсов. Как отдельных сущностей. По факту все есть объект и все строит из них.
наследование реализуется выстраиванием цепочки прототипов. Инкапсуляция только на уровне scope'в (читай замыканий).
В остальном все меняется и все динамично, если только специально все не зафризить в момент конструирования. Но обычно этим никто не заморачивается по причине оверхеда и бессмысленности. Разве только фанатики по иммутабельности, н это все из разряда те, кому надо чтобы им по рукам бил компилятор\рантайм\дядя петя. Все "привычные" понятия тянуться в язык для еще более простого вкатывания тех, кто приходит из других языков. Так уж сложилось, что есть куча литературы по привычному, статически классовому ООП, но очень мало по мессадж-пассинг\прототайп-базед\мета-программинг. Все эти притянутые понятия выливают в синтаксический сахар, который не делает ничего полезного, а даже наоборот, еще больше вносит путаницы и от того непонимамания многих вещей в языке. При этом часто этот синтаксический сахар дэже урезан и вспомнинают об этом лишь после (как например проебались с полями в конструкции class и тянут ее теперь только в proposol'ах будущих версий).

JS истинно объектный язык. В современный язык притащили много вкусных вещей для метапрограммирования. Нову примитивную сущность Symbol, и Proxy-объекты. С помощью которых можно еще больше и сильнее перегружать и менять поведение в динамике.

Другое дело, что почти никто не умеет этим пользоваться и не понимает, что такое объектное программирование на самом деле.
Им нужно не объектное, а статически типизированное. А какие именно структуры будут скрываться за этими типами, не собо важно. Важно что это просто структуры и функции, строго привязанные к ним, или иногда менее строго. То, что в Java\C++ это больше структурное программирование, нежели объектное. Объектное программирование не может существовать без динамической среды. Это противоречит самому понятию объекта. А динамическое программирование это слишком сложна и непанятна. И как бы не старались с пеной у рта фанатики кричать про низкий порог входа - низкий он именно что для входа, а не для всего остального. Модификация программ в рантайме всегда было уделом креативно мыслящих людей. Для большинства это слишком сложный уровень высокой абстракции.
Ответы: >>1273629 >>1273635
Аноним 2018/10/02 19:34:31  №1273629 5
>>1273613

Примитив это все же не объект. Простой пример:

var a = 6;
a.x = 1;
console.log(a.x); // undefined
Ответы: >>1273639
Аноним 2018/10/02 19:41:22  №1273635 6
>>1273613
ты охуенен. Посоветуй литературу для развития или сайты. Да чего угодно. Не доку по жс или реакту, а вообще что-то типо шаблонов и современном программировании, подходов к разработке и т.д. что "сложна и непанятна".

>Модификация программ в рантайме всегда было уделом креативно мыслящих людей. Для большинства это слишком сложный уровень высокой абстракции.
Аноним 2018/10/02 19:53:18  №1273639 7
image.png (28, 485x294)
294x485
image.png (136, 778x590)
590x778
>>1273629

Читай внимательнее
> их можно тоже рассматривать в качестве синглтон объектов

И во-первых - пик 1.
Во-вторых - пик 2.

Ответы: >>1273677
Аноним 2018/10/02 22:12:09  №1273677 8
>>1273639
Нифига себе волшебство.