Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Использование классов в JavaScript (https://javascript.ru/forum/project/27339-ispolzovanie-klassov-v-javascript.html)

devote 10.04.2012 05:25

Использование классов в JavaScript
 
Эмуляция классов в JavaScript

Библиотека дает писать код с возможностями классового программирования. В JavaScript нет классов, но есть прототипы. Собственно используя возможности языка, я попытался реализовать некую обертку, которая более или менее приближено показывает как можно использовать классовое программирование на языке JavaScript.

Возможности библиотеки на мой взгляд вполне адекватны, поэтому при желании можно на ее основе построить огромный проект. Скорость работы кода с использованием данной библиотеки в целом не падает. Она старается максимально оптимизировать структуру классов. Библиотека работает во всех нынешних браузерах, даже в таком браузере как IE7, возможно даже в IE6 (Но я этого не проверял).

Методы:

Класс в текущем контексте
Class(Object/Function classStructure) : Function
// Объект в качестве аргумента
var MyClass = Class({
    method: function() {
    }
});
var instanceMyClass = new MyClass;
instanceMyClass.method();

// Функция для инкапсуляции в качестве аргумента
var MyClass = Class(function() {
    // инкапсуляция для каждого экземпляра своя
    var privateVariable = null;
    return {
        method: function() {
            return privateVariable;
        }
    }
});
var instanceMyClass = new MyClass;
instanceMyClass.method();
Класс в указанном пространстве имен
Class(String className, Object/Function classStructure) : Function
// Глобальное пространство имени
Class("MyClass", {
    ...
});
var instanceMyClass = new MyClass;

// пространство имени NS
Class("NS.MyClass", {
    ...
});
var instanceMyClass = new NS.MyClass;
Класc с наследованием
Class([String className,] Function parent, Object/Function classStructure) : Function
Class("ParentClass", {
    methodOfParent: function() {
        // ...
    }
});

// создаем класс наследуемый от ParentClass
var MyClass = Class(ParentClass, {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent(); // Метод получим из класса ParentClass

// или
Class("MyClass", ParentClass, {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent(); // Метод получим из класса ParentClass
Класc с множественным наследованием
Class(String className, String extends, Object/Function classStructure) : Function
Class("ParentClass1", {
    methodOfParent1: function() {
        // ...
    }
});
Class("ParentClass2", {
    methodOfParent2: function() {
        // ...
    }
});

Class("MyClass", "ParentClass1, ParentClass2", {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent1(); // Метод получим из класса ParentClass1
instanceMyClass.methodOfParent2(); // Метод получим из класса ParentClass2

Другие вариации и методы
Class([String className, ][Object options, ][Object/Function classStructure]) : Function
Все параметры являются не обязательными.

Параметры:
  • className: String
    Параметр задает имя класса в контексте который мы укажем, поддерживается любое пространство имени, разделяя их точкой.
  • options: Object
    Этот параметр задает начальные опции для класса, такие как контекст в котором будет создан класс, наследники и статические свойства, подробнее о них я расскажу позже.
  • classStructure: Object/Function
    Параметр задает структуру класса, объект с вашими свойствами, методами. Разрешено указывать функцию в качестве аргумента, которая будет возвращать построенную структуру класса, это иногда удобно, когда например нужно использовать приватные методы/свойства.
Все параметры являются не обязательными, а значит вы можете пропустить тот или иной параметр, к примеру не указывать имя класса и начинать описывать опции или структуру класса, при этом опущенный параметр не нужно чем то закрывать, просто вместо него пишите то что идет за ним.
Возвращаемое значение : Function
Возвращает ссылку на конструктор созданного класса
Class.instanceOf( Object object, Function constructor ) : Boolean
Проверяет принадлежность объекта к указанному классу, простыми словами проверяет является ли объект наследником класса.

Параметры:
  • object: Object
    Объект, экземпляр класса, который будет проверяться на принадлежность к указанному классу.
  • constructor: Function
    Ссылка на класс, который будет проверятся является ли он потомком указанного объекта в первом параметре.
Возвращаемое значение : Boolean
Метод вернет true если объект является наследником класса, в противном случае вернет false
Class.imports( String/String[] url [, Function onLoad [, Function onError ]] )
Метод импортирует и исполняет .js файлы, поддерживает как синхронную, так и асинхронную загрузку.

Параметры:
  • url: String/String[]
    Параметр поддерживает два типа входных данных, это строку или массив строк. В качестве строк выступают ссылки на файлы которые будут импортированы.
  • onLoad: Function - Не обязательный
    Параметр принимает функцию, которая будет вызвана по окончании загрузки всех указанных файлов. Если этот параметр не задан, будет выполнятся синхронный режим загрузки.
  • onError: Function - Не обязательный
    Параметр принимает функцию, которая будет вызвана при возникновении ошибки во время загрузки файлов, если эта функция вернет значение true, то загрузка остальных файлов будет продолжена.

Использование:

Использование библиотеки очень простое, и немногим схожа с объявлениями классов например в PHP
Код в PHP:
class Foo {
    // структура класса
}
Код в JavaScript
Class( "Foo", {
    // структура класса
});
Как видите, сходство достаточно близкое. Я не стал придумывать что-то новое и попытался реализовать эмуляцию классов схожую к привычной в классовом программировании.

Сейчас я немного расскажу о дополнительных параметрах, которые указываются в объекте options, описанный ранее в описании метода Class.
  • context: Object
    Параметр указывает конструктору классов, о том куда нужно разместить ссылку на объявленный класс. По умолчанию все объявленные классы, попадают в глобальное пространство window, в нем создается свойство с именем класса, имеющее ссылку на объявленный класс
  • extend: String/Function
    Параметр указывает о том от кого нужно унаследовать свойства. Параметр может быть двух типов.
    String - строка содержащая имя класса от которого будет унаследован объявленный класс, поиск класса родителя будет произведен в том же контексте в котором объявляется класс.
    Function - ссылка на конструктор класса, может находится совершенно в любом пространстве имен.
  • mixins: String/Function/String[]/Function[]
    Дает возможность организовать множественное наследование. Множественное наследование ни чем не ограничено от обычного наследования.
    Значение может иметь как строку с именем наследуемого класса, так и конструктор наследуемого класса. Так же параметр может иметь тип массива, в котором будут указанны по порядку строки или конструкторы наследуемых классов.
  • statics: Object
    Объект со статическими свойствами
Определение класса:
Class("SimpleClass", {
    // свойства класса
    ...
});

Конструкторы:

конструкторы есть двух типов, первый это метод имеющий такое же имя как имя класса:
Class("SimpleClass", {
    SimpleClass: function() {
        // будет вызван при создании экземпляра
    }
});
Второй вариант имеет всеми привычное имя: constructor, часто удобен при создании анонимных класов:
var SimpleClass = Class({
    constructor: function() {
        // будет вызван при создании экземпляра
    }
});


... описал бы больше, но тут лимит в 10000 символов на пост(((

Типы и различия в файлах библиотек:
class.js        - Полная версия библиотеки, включает в себя все что описано выше.
class.min.js    - Сжатая с помощью GCC.
Скачать все это можно на GitHub: https://github.com/devote/jsClasses

Pavel M. 10.04.2012 08:02

не знал, что setter's/getter's можно реализовать для старых ie через vbscript, спасибо

FINoM 10.04.2012 17:04

Чтобы не было столько минусов, нужно было написать «В JAVASCRIPT НЕТ КЛАССОВ, НИЖЕ ИЗЛОЖЕН ОДИН ИЗ СПОСОБОВ ЭМУЛЯЦИИ»

devote 10.04.2012 17:31

Цитата:

Сообщение от FINoM
Чтобы не было столько минусов

Ну меня собственно не расстраивают минусы. Если людям нравится жать кнопку "-" то пусть жмут на здоровье, а те кто нормально прочтут статью и поймут в чем профит. Просто добавят в избранное или просто пройдут мимо.

Минусы как правило ставят те кто читал подобные статьи, но не удосужился прочесть эту. А просто включив опцию "стада" в голове пошел ставить минус. Уж таковы реалия и с этим ничего не поделаешь.

PS. Писать статьи я не мастак, а точнее не писал никогда. От того и недопонимание у некоторых людей возникают.

melky 10.04.2012 17:34

я обхожусь встроенными средствами. классы - на любителя.

Цитата:

Сообщение от Pavel M. (Сообщение 168035)
не знал, что setter's/getter's можно реализовать для старых ie через vbscript, спасибо

то же самое.

devote, не поделитесь секретом ?

FINoM 10.04.2012 17:36

Честно сказать, лучше бы сделал либу для поддержки какой-нибудь фигни из ES.next.
Цитата:

Сообщение от devote
От того и недопонимание у некоторых людей возникают.

Это не отменяет того факта, что, в первую очередь, нужно вводить людей в тему, пускай и кратко. Сочинения, ведь, в школе писал.

FINoM 10.04.2012 17:36

Цитата:

Сообщение от melky
devote, не поделитесь секретом ?

http://webreflection.blogspot.com/20...6-7-and-8.html

devote 10.04.2012 17:39

Цитата:

Сообщение от melky
devote, не поделитесь секретом ?

А секрета как такового и нет, эта возможность имеет ограничения, и лишь подобная обертка дает возможность использовать ограниченные возможности ишака.
Цитата:

Сообщение от FINoM
Сочинения, ведь, в школе писал.

прогуливал :D литература/русский для меня темный лес всегда были.

FINoM 10.04.2012 17:42

Цитата:

Сообщение от devote
литература/русский для меня темный лес всегда были.

То же самое, но есть очень простое правило любой публикации: введение, суть, заключение.

melky 10.04.2012 17:53

Цитата:

Сообщение от FINoM (Сообщение 168160)

логичней бы было кинуть ссылку сразу на код


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