Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   Как работает функция Class (https://javascript.ru/forum/offtopic/33909-kak-rabotaet-funkciya-class.html)

godofjavascript 13.12.2012 19:14

Как работает функция Class
 
В этом посте мы рассмотрим пошагово как устроена изнутри всеми нами любимая функция Class.


Вначале я создал красивую обертку под описание классов:
function Class(Prototype) {

    function Class() {
        /** @namespace this.__construct */
        if (this.__construct)this.__construct.apply(this, arguments)
    }

    Class.prototype = new Prototype;

    return Class
}


var Cat = new Class(function () {

    this.__construct = function (name) {
        this.name = name || 'Neo';
    };

    this.say = function () {
        alert(this.name)
    };

});


new Cat().say();

Благодаря чему теперь можно описывать свойства методы и конструктор все в одном изолированном месте и ни чего больше не болтается)


Потом я добавил возможность добавлять классу статические свойства(8 строчка):

function Class(Prototype) {

    function Class() {
        /** @namespace this.__construct */
        if (this.__construct)this.__construct.apply(this, arguments)
    }

    Class.prototype = new Prototype(Class);

    return Class
}


var Cat = new Class(function (Cat) {
    Cat.ololo = 11;
});

alert(Cat.ololo);



Далее я добавил возможность классам наследоваться друг от друга(9 строчка):

function Class(Prototype, superclass) {

    function Class() {
        /** @namespace this.__construct */
        if (this.__construct)this.__construct.apply(this, arguments)
    }


    if (superclass) Prototype.prototype = superclass.prototype;
    Class.prototype = new Prototype(Class);

    return Class
}


var Animal = new Class(function () {
    this.run = function () { alert('run') };
});

var Cat = new Class(function () {
    this.jump = function () { alert('jump') };
}, Animal);


new Cat().run();
new Cat().jump();



Потом я добавил возможность обращения к перекрытым методам через this.super(12-26 строчка):
function Class(Prototype, superclass) {

    function Class() {
        /** @namespace this.__construct */
        if (this.__construct)this.__construct.apply(this, arguments)
    }

    if (superclass) Prototype.prototype = superclass.prototype;
    Class.prototype = new Prototype(Class);


    if (superclass) for (var key in Class.prototype)
        if (Class.prototype.hasOwnProperty(key)
            && key in Prototype.prototype
            && Class.prototype[key] instanceof Function
            && Prototype.prototype[key] instanceof Function)
        {
            Class.prototype[key] = (function (key) {
                var method = Class.prototype[key];

                return function () {
                    this.super = Prototype.prototype[key];
                    return method.apply(this, arguments)
                }
            })(key)
        }

    return Class
}


var Animal = new Class(function () {
    this.run = function () {
        alert('run')
    };
});

var Cat = new Class(function () {
    this.run = function () {
        this.super();
        alert('...and jump')
    };
}, Animal);


new Cat().run();


ВСЁ)) А больше ни чего и не нужно) дальше уже ваша фантазия что с этим делать. Шаблоны того как я этим работать и зачем это вообще нужно я уже предлагал) Кто прочел, тот молодец.


-----------------------------------------------------
Почему я сделал

var Ololo = new Class(function(){  });


а не

var Ololo = Class.extends(function(){  });


Потому что new Class очевиднее чем Class.extends или Ololo.extends

DjDiablo 13.12.2012 19:18

Я уже ненавижу функцию Class.
Если ещё хоть одна сволочь покажет мне как эмитировать классы я его убью к чёрту :-E

godofjavascript 13.12.2012 19:19

Еще один человек думающий что функция Class пытается эмитировать классы из других языков в javascript'е... Тысячи их.. Не обращаем внимание, он не глупый и не "плохой", он просто не читал описание к первым версиям функции. Не судите его строго, его можно понять.

Shaci 13.12.2012 19:23

опять максимус со своими котятами

godofjavascript 13.12.2012 19:26

о, уже кому-то припекло...

DjDiablo 13.12.2012 19:32

Точняк максимальноМинимальный
блин а я повёлся ))

godofjavascript 13.12.2012 19:42

Цитата:

Сообщение от DjDiablo
Я уже ненавижу функцию Class.

Не читай топик, в чем проблема, меня просили написать как она работает - я пишу. Кому интересно - почитают.

Riim 14.12.2012 06:45

this.super как я понял вызывает одноименный (к тому из которого он вызывается) метод?

godofjavascript 14.12.2012 08:32

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

п.с. напомню что это просто обьяснение того как Class работает, на самом деле там еще немного рющек навешано, и оптимизаций. а также можно менять слово super на какое понравится.

melky 14.12.2012 17:49

навскидку, instanceof не работает ...

godofjavascript 14.12.2012 23:00

Цитата:

Сообщение от melky
навскидку, instanceof не работает ...

работает (кэп подсказывает что это не функция класс, это примерно то как она устроенна, на функции класс все работает и еще куча ништяков, как мы помним, тут я пытался опсиать лишь логику того как она работает, не затрагивая то как там протектед от приват отличаются и прочее)

godofjavascript 15.12.2012 00:05

и ДА, на каждый перекрываемый метод родительского класса в дочернем создает замыкание. И я думаю потеря в 50 миллисекунд на 1000000 операций того стоит.

все ради того чтобы писать не (как в педыдущих версиях)

patent.run.apply(this, arguments);

а

this.super();



п.с. к слову, в оригинальной версии работает даже
new Cat instanceof Cat // true
new Cat instanceof Animal // true
new Cat instanceof Class // true

и
Class.prototype.q = 11
new Cat().q // 11


и все это с поддержкой ie 6

Shaci 15.12.2012 00:41

Цитата:

Сообщение от godofjavascript
и все это с поддержкой ie 6

когда ж этот браузер сдохнет..

godofjavascript 15.12.2012 09:23

если бы не ишаки то добавил бы фиксированный this и define property

а вообще официально можно поддерживать только текущую и предыдущую версии чего-либо.. то есть щас ишак 10 и 9, 8 уже можно больше не пддерживать и посылать всех нахуй.

godofjavascript 15.12.2012 09:28

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

Иначе мы не сможем сделать нормальное наследование. Например:
function Button (){
    document.createElement('div')
}

function Toggle (){
   /* бла бла бла преключатель на основе кнопки */ 
}
Toggle.prototype = new Button;


ТАК ШТОЛЕ НАМ НАСЛЕДОВАНИЕ ДЕЛАТЬ? Вот и я про то, конструктор должен быть методом (в нашем случае это протектед метод __construct который наследуется и скрытый)


А так же затем чтобы можно было удобно обращаться к перекрытым родительским методам через this.super().

а не так :

this.run = function(){
  Object.getPrototypeOf(this).run.apply(this,arguments);
  alert('...and jump')
}


все, больше у этой байды назначений нет. если вы не пользуете наследование в своих проектах то Class и нахуй не нужна.

И вообще, для тех кто не понимает что такое ооп и что такое классы вообще, чтобы вы не плакались, замените название функции на Type.

DjDiablo 15.12.2012 12:20

Цитата:

а вообще официально можно поддерживать только текущую и предыдущую версии чего-либо.. то есть щас ишак 10 и 9, 8 уже можно больше не пддерживать и посылать всех нахуй.
это только в астральном вакууме можно посылать всех.

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

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

Просто тупые - ты гордо говоришь что сделал, клиент идёт домой запускает XP, запускает 7й ишак с кучей плагинов на пол экрана :) и видит что ничего не работает. В истерике звонит тебе и начинает орать что он заплатил деньги, что вы долго долго делали и всё равно ни хуя не работает. Короче вы уроды, недоучки и дебилы в его глазах, и вообще он хочет обратно свои деньги и никогда работать с вами он больше не будет.

умные - у них есть статистика по браузерам посетителей их ресурса. И тут выясняется что допустим целевая аудитория врачи, основная ось на рабочих пк у них XP, установка программ обычно запрещена администратором компов. Получается что часть бедолаг сидит тна 7мом а то и 6м ишаке. Заказчик видит эту статистику, звонин вам и обьясняет "дык ребят я всё понимаю но я немогу позволить себе пожертвовать 20% посетителей", и ты либо отказываешся от заказа либо выполняешь его требования.

Требования определяет заказчик а ни программист. Иногда требования некорректны иногда противоречивы или невыполнимы(прим HTML5 CSS3 анимацию на 6ie). Но с требованиями нужно и можно работать, существует даже такое направление как инженерия требований, существует специальность инженер по требованиям (редко- редко). А вот посылать, просто потому что не хочется что-то делать можно только в фантазиях.

melky 15.12.2012 13:07

Цитата:

Сообщение от godofjavascript
все ради того чтобы писать не (как в педыдущих версиях)

Цитата:

Сообщение от godofjavascript
если вы не пользуете наследование в своих проектах то Class и нахуй не нужна.

имхо JS функциональный язык с добавлением (чуть-чуть) прототипного ООП - это стало ясно уже после JS 1.6 (reduce, maps, filters <-- Array); для текущей версии это уже очевидно - ребята даже синтаксис функций упрощают, дабы они стали похожими на лямбды:
// JS 1.5
function () { return false; } 
// JS не помню какой версии
function () false;


тем более, что на хабре начали всё чаще публиковать статьи про ФП - почему бы не перейти? кода действительно намного меньше получается.

Цитата:

Сообщение от DjDiablo
прим HTML5 CSS3 анимацию на 6ie

я ещё ломаю голову :)

fadeIn и fadeOut программируется на фильтрах - я хочу сказать, что это то же самое, что и css3 анимация.

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

tenshi 15.12.2012 13:56

какой нафиг функциональный язык если "функции" в js являются объектами?

godofjavascript 15.12.2012 14:25

Цитата:

Сообщение от DjDiablo
тут выясняется что допустим целевая аудитория врачи, основная ось на рабочих пк у них XP, установка программ обычно запрещена администратором компов.

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

Цитата:

Сообщение от DjDiablo
А вот посылать, просто потому что не хочется что-то делать можно только в фантазиях.

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

Цитата:

Сообщение от tenshi
какой нафиг функциональный язык если "функции" в js являются объектами?

забаньте его уже а

Цитата:

Сообщение от melky
анимировать смену innerHTML

даа, в ишаке много че напридумывали, только вот они забивали хуй на стандарты, по тому он и говно, если бы там была поддержка И стандартов И их нововведений, тогда это был бы хром)

dmitriymar 15.12.2012 15:26

Цитата:

Сообщение от godofjavascript
в чем проблема, меня просили написать как она работает - я пишу

кто и когда, если не секрет? может приснилось ? а?:)

DjDiablo 15.12.2012 15:58

Цитата:

то тебе придется делать все за что заплатят.
Ну суть в том что ты должен что то сделать полезное для общества чтобы оно дало что то тебе в замен (даже в СССР так было). А если ты сделаешь что-то так как хочется тебе но другим это нужно, то вероятно взамен своей работы ты нечего не получишь.

Можешь делать по своему, в конце концов интегрироваться ли тебе в общество решай сам. Если всё таки решишь интегрироваться то будешь считаться с чужими потребностями а не только со своими.

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

melky 15.12.2012 16:02

Цитата:

Сообщение от tenshi
какой нафиг функциональный язык если "функции" в js являются объектами?

объектами первого класса.

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

Riim 15.12.2012 16:49

Цитата:

Сообщение от godofjavascript
только вот они забивали хуй на стандарты

тогда стандартов толком не было.

godofjavascript 15.12.2012 17:24

Цитата:

Сообщение от DjDiablo
Ну суть в том что ты должен что то сделать полезное для общества чтобы оно дало что то тебе в замен

В обществах основанных на труде мжоет оно и так. Да только вот ишак вредит, ишак это плохой браузер на котором ни кто не хочет сидеть, и потакать этому - вредить обществу, а не наоборот. Потакать этому означало бы думать только о себе и о копеечке которую получишь, означало бы быть шлюхой а не заботиться об общстве и пересаживать их на хром. Заботиться Это подобно тому как не зассать и сказать что земля круглая когда все думают что она плоская. ЭТО означало бы заботиться об обществе, а не быть его шлюхой и прогибаться под всех лишь бы угодить им. Разве нет?

Цитата:

Сообщение от Riim
тогда стандартов толком не было.

пруф (можешь не искать, стандарты были)

Riim 15.12.2012 17:36

Цитата:

Сообщение от godofjavascript
можешь не искать, стандарты были

были то были, только кто их писал? Разработчики браузеров, которые по возможностям отстали минимум лет на 10? А что им еще оставалось, кроме как написать типа самые правильные стандарты, идеально подходящие под их на тот момент возможности, а потом говорить: ну у нас же все по стандартам, это в ИЕ какая-то черная магия.

tenshi 15.12.2012 17:36

Цитата:

Сообщение от melky (Сообщение 221502)
объектами первого класса.

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

то, что это обычные объекты, но которые содержат настоящую функцию в скрытом поле [[Call]] или как там оно называется, а не функции из ФП. общего у них - только название. кроме того, ФП - оно вообще не о функциях первого класса. оно прежде всего об отсутствии побочных эффектов. в яваскрипте с его прототипной моделью это вообще невозможно, так как кто угодно может насрать в прототипы и изменить поведение функции до неузнаваемости. как следствие - невозможность всяких оптимизаций и в том числе автоматического распарралеливания.

godofjavascript 15.12.2012 17:39

Кто нибудь понимает вообще что несет этот человек?

tenshi 15.12.2012 18:04

подрастёшь - поймёшь

godofjavascript 15.12.2012 18:08

насрать в прототипы, изменить поведения функции какие-то, ты понмиаешь что ты поехал, все уже?

melky 15.12.2012 19:37

Цитата:

Сообщение от godofjavascript
Кто нибудь понимает вообще что несет этот человек?

я его отлично понимаю :)

Цитата:

Сообщение от tenshi
то, что это обычные объекты, но которые содержат настоящую функцию в скрытом поле [[Call]] или как там оно называется, а не функции из ФП.

на уровне движка - да.

выражения, что там, что там. какая разница?

разница только в том, что 2+2 V8 сразу превратит в 4, а в хаскеле так и останется 2+2, но ленивость можно самому сэмулировать.

Цитата:

Сообщение от tenshi
ФП - оно вообще не о функциях первого класса

и речи не было :)

Цитата:

Сообщение от tenshi
оно прежде всего об отсутствии побочных эффектов.

то, что в функциях JS есть побочные эффекты, это не значит, что можно писать без них (просто не трогать ничего, кроме локальных аргументов, например)

Цитата:

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

у функции можно убрать только изменения контекста \ bind - но в ФП нет понятия контекста и каррирование можно делать без bind.

Цитата:

Сообщение от tenshi
как следствие - невозможность всяких оптимизаций и в том числе автоматического распарралеливания

это да. но посмотрим, может в будущем что-нибудь изменится

Tim 15.12.2012 20:11

Цитата:

Сообщение от DjDiablo (Сообщение 221153)
Точняк максимальноМинимальный
блин а я повёлся ))

А я в одной из предыдущих его ещё сказал про это. Он даже ник не похожий на один из предыдущих свох ников придумать не может.

tenshi 15.12.2012 23:43

> выражения, что там, что там. какая разница?

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

> в хаскеле так и останется 2+2
да ладно?

> то, что в функциях JS есть побочные эффекты, это не значит, что можно писать без них (просто не трогать ничего, кроме локальных аргументов, например)

нельзя? в том то и дело, что нельзя. я не могу гарантировать что функция function(){ return 'Array:' + [] } всегда возвращает один и тот же результат. и компилятор не может. это уже не функция в терминах ФП, так как значение зависит не только от аргументов.

> это да. но посмотрим, может в будущем что-нибудь изменится

разве что введут ключевое слово pure, но это врятли, так как вместо этого изобретают всяких "воркеров".

melky 16.12.2012 01:00

Цитата:

Сообщение от tenshi
да ладно?

почему нет то?
Цитата:

Сообщение от tenshi
я не могу гарантировать что функция function(){ return 'Array:' + [] } всегда возвращает один и тот же результат.

гм ... ты так говоришь, будто у нас такой код везде встроен :
Array.prototype.toString = function () { return Math.random(); };


Цитата:

Сообщение от tenshi
так что js от пяток до макушки - ООП.

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

godofjavascript 16.12.2012 01:21

Цитата:

Сообщение от melky
я его отлично понимаю

я тоже понимаю что он говорит)) он говорит слова, но если образовать их в предложения то предложения не имеют смысла))) то есть не то чтобы он был, а я его не понимал, его нет)

Цитата:

Сообщение от melky
то, что в функциях JS есть побочные эффекты, это не значит, что можно писать без них

ВОООООООООООООТ, и я про то, че он несет что РАЗ МОЖНО СДЕЛАТЬ ПОбОЧНОСТЬ то значит не фп, это же бред)) он совсем поехал, всё уже.. какие т там прототипы и их изменение на какие то там функции влияет.. начальник, дурку вызывай.

Цитата:

Сообщение от melky
как следствие - невозможность всяких оптимизаций и в том числе автоматического распарралеливания

как следствие ЧЕГО?? Того чт о ты выше описал? пруф что то что ты выше описал вообще имеет смысл и мешает сделать движкам автоматическое ркапараллеливание)) я звоню в дурку нахрен...

Цитата:

Сообщение от Tim
Он даже ник не похожий на один из предыдущих свох ников придумать не может.

ахахха

nerv_ 16.12.2012 01:34

tenshi, melky, вы зафлудили тему про его любимую функцию Class. Он не переживет :D

Shaci 16.12.2012 02:31

Цитата:

Сообщение от godofjavascript
Он даже ник не похожий на один из предыдущих свох ников придумать не может

постоянно слово god в никах проскальзывает)))

godofjavascript 16.12.2012 03:06

небольшое завышение чсв

Deff 16.12.2012 03:27

godofjavascript,
Не заморачивайтесь, подобные темы нун выстаивать холодными, как студень, тады через время осознаюца плюсы и минусы,
Каждый скриптёр видит своим долгом создать функции класса - тут кого ни ткни пальцем - не попадёте в того, кто не делал - отсель и скепсис

godofjavascript 16.12.2012 03:57

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


Я вроде бы писал уже чем эта функция отличется от остальных и вообще зачем она нужна. Нет?

melky 16.12.2012 10:32

godofjavascript, очевидно, что это простая обёртка над прототипами, нет?


Часовой пояс GMT +3, время: 11:37.