В основе архитектуры библиотеки лежит минималистичная объектная
система, реализованная через CryptoJS.lib.Base. Она задаёт
единый способ создания «классов», расширения функциональности и
построения иерархий без использования нативных классов ES6 (библиотека
исторически ориентирована на более раннюю модель JavaScript).
Ключевая идея заключается в том, что каждый «класс» в системе
CryptoJS — это функция-конструктор, расширяемая через метод
extend, предоставляемый базовым объектом
Base.
var MyClass = CryptoJS.lib.Base.extend({
init: function (arg) {
this.value = arg;
}
});
Здесь extend создаёт новый конструктор, который
наследует поведение базового объекта и добавляет или переопределяет
методы.
CryptoJS.lib.Base выступает фундаментом всей объектной
модели библиотеки. Он содержит минимальный набор механизмов:
Упрощённо его можно представить как:
var Base = {
extend: function (overrides) { ... },
create: function () { ... },
init: function () {}
};
Главная логика наследования реализована в Base.extend.
Он создаёт новый конструктор и связывает его с родительским объектом
через прототип.
Механизм включает несколько шагов:
Упрощённая схема:
extend: function (overrides) {
var Parent = this;
var Child = function () {
if (this.init) {
this.init.apply(this, arguments);
}
};
Child.prototype = Object.create(Parent.prototype);
for (var key in overrides) {
Child.prototype[key] = overrides[key];
}
Child.prototype.constructor = Child;
Child.extend = Parent.extend;
return Child;
}
Вместо стандартного конструктора используется соглашение
init. Это позволяет унифицировать поведение всех
классов.
var WordArray = CryptoJS.lib.Base.extend({
init: function (words, sigBytes) {
this.words = words;
this.sigBytes = sigBytes;
}
});
При создании объекта через extend фактический вызов
конструктора делегируется init, что обеспечивает единый
стиль инициализации.
Базовый класс также предоставляет метод create, который
используется вместо new.
var instance = MyClass.create(arg);
Реализация обычно выглядит как обёртка над new:
create: function () {
var instance = Object.create(this.prototype);
this.apply(instance, arguments);
return instance;
}
Это позволяет скрыть детали конструктора и унифицировать создание объектов во всей библиотеке.
Каждый новый «класс» в CryptoJS связан с родительским через прототипную цепочку. Это обеспечивает:
При вызове метода движок JavaScript поднимается по цепочке:
Child.prototype → Parent.prototype → Base.prototype
Таким образом, если метод не найден в текущем объекте, он ищется выше по иерархии.
При расширении класса можно заменять существующие методы. Это основной механизм кастомизации.
var A = CryptoJS.lib.Base.extend({
getValue: function () {
return 1;
}
});
var B = A.extend({
getValue: function () {
return 2;
}
});
В B метод getValue перекрывает реализацию
родителя.
В классической реализации CryptoJS отсутствует нативный
super, но доступ к родительской логике возможен через
сохранение ссылки на прототип.
Часто используется паттерн сохранения базового метода:
var ParentMethod = this.someMethod;
this.someMethod = function () {
ParentMethod.apply(this, arguments);
};
Либо через явное обращение к прототипу:
CryptoJS.lib.Base.prototype.method.call(this);
Помимо наследования, Base поддерживает примитивную
композицию поведения через копирование свойств.
При вызове extend любые дополнительные поля из объекта
overrides просто копируются в прототип.
extend: function (overrides) {
for (var key in overrides) {
this.prototype[key] = overrides[key];
}
}
Это делает возможным добавление функциональности без создания сложной иерархии.
Практически все структуры библиотеки строятся на
Base:
CryptoJS.lib.WordArrayCryptoJS.lib.CipherCryptoJS.lib.HasherCryptoJS.lib.StreamCipherКаждая из них расширяет базовый объект и добавляет специфичную криптографическую логику.
Например, Hasher добавляет:
Архитектура Base используется не только как инструмент
ООП, но и как механизм стандартизации поведения алгоритмов.
Все криптографические примитивы следуют одному контракту:
init — инициализация состоянияupdate — обработка данныхfinalize — завершение вычисленияЭтот контракт реализуется через наследование от базовых классов, где
Base задаёт структуру расширения.
Метод extend имеет несколько характерных особенностей,
отличающих его от классических паттернов:
Object.createextendВместо строгой инкапсуляции используется соглашение о приватности:
_property — внутренние поляvar Example = CryptoJS.lib.Base.extend({
_buffer: null,
process: function () {
this._buffer = [];
}
});
Такой подход упрощает структуру, но оставляет внутреннюю логику доступной при необходимости.
CryptoJS.lib.Base реализует крайне лёгкую систему
объектной ориентации:
Это сделано для обеспечения:
Благодаря унифицированной модели наследования:
Структура позволяет строить сложные цепочки обработки данных без изменения ядра библиотеки.
Несмотря на гибкость, модель имеет ограничения:
superТем не менее, в контексте криптографических операций эти ограничения компенсируются простотой и предсказуемостью выполнения.