کاوش دکوراتورهای جاوا اسکریپت، فراداده و بازتاب برای باز کردن قفل دسترسی قدرتمند به فراداده در زمان اجرا، فعال کردن قابلیت های پیشرفته، بهبود قابلیت نگهداری و انعطاف پذیری بیشتر در برنامه های شما.
دکوراتورهای جاوا اسکریپت، فراداده و بازتاب: دسترسی به فراداده در زمان اجرا برای قابلیت های پیشرفته
جاوا اسکریپت، که فراتر از نقش اولیه اسکریپت نویسی خود تکامل یافته است، اکنون زیربنای برنامه های پیچیده وب و محیط های سمت سرور است. این تکامل مستلزم تکنیک های برنامه نویسی پیشرفته برای مدیریت پیچیدگی، افزایش قابلیت نگهداری و ترویج استفاده مجدد از کد است. دکوراتورها، یک پیشنهاد مرحله 2 ECMAScript، همراه با بازتاب فراداده، یک مکانیسم قدرتمند برای دستیابی به این اهداف با فعال کردن دسترسی به فراداده در زمان اجرا و پارادایم های برنامه نویسی جنبه گرا (AOP) ارائه می دهند.
درک دکوراتورها
دکوراتورها نوعی شیرین کننده نحوی هستند که روشی مختصر و اعلانی برای تغییر یا گسترش رفتار کلاس ها، متدها، خصوصیات یا پارامترها ارائه می دهند. آنها توابعی هستند که با نماد @ پیشوند می شوند و بلافاصله قبل از عنصری که تزئین می کنند قرار می گیرند. این امر امکان افزودن نگرانی های متقابل، مانند ثبت وقایع، اعتبارسنجی یا مجوز، بدون تغییر مستقیم منطق اصلی عناصر تزئین شده را فراهم می کند.
یک مثال ساده را در نظر بگیرید. تصور کنید که باید هر بار که یک متد خاص فراخوانی می شود، ثبت کنید. بدون دکوراتورها، باید به صورت دستی منطق ثبت را به هر متد اضافه کنید. با دکوراتورها، می توانید یک دکوراتور @log ایجاد کنید و آن را روی متدهایی که می خواهید ثبت کنید اعمال کنید. این رویکرد منطق ثبت را از منطق اصلی متد جدا نگه می دارد و قابلیت خوانایی و نگهداری کد را بهبود می بخشد.
انواع دکوراتورها
چهار نوع دکوراتور در جاوا اسکریپت وجود دارد که هر کدام هدف مشخصی را دنبال می کنند:
- دکوراتورهای کلاس: این دکوراتورها سازنده کلاس را تغییر می دهند. آنها می توانند برای افزودن ویژگی ها، متدها یا تغییر موارد موجود استفاده شوند.
- دکوراتورهای متد: این دکوراتورها رفتار یک متد را تغییر می دهند. آنها می توانند برای افزودن منطق ثبت، اعتبارسنجی یا مجوز قبل یا بعد از اجرای متد استفاده شوند.
- دکوراتورهای ویژگی: این دکوراتورها توصیفگر یک ویژگی را تغییر می دهند. آنها می توانند برای پیاده سازی اتصال داده، اعتبارسنجی یا مقداردهی اولیه تنبل استفاده شوند.
- دکوراتورهای پارامتر: این دکوراتورها فراداده ای در مورد پارامترهای یک متد ارائه می دهند. آنها می توانند برای پیاده سازی تزریق وابستگی یا منطق اعتبارسنجی بر اساس انواع یا مقادیر پارامتر استفاده شوند.
نحو اولیه دکوراتور
یک دکوراتور تابعی است که بسته به نوع عنصر تزئین شده، یک، دو یا سه آرگومان می گیرد:
- دکوراتور کلاس: سازنده کلاس را به عنوان آرگومان خود می گیرد.
- دکوراتور متد: سه آرگومان می گیرد: شی هدف (یا تابع سازنده برای یک عضو استاتیک یا نمونه اولیه کلاس برای یک عضو نمونه)، نام عضو و توصیفگر ویژگی برای عضو.
- دکوراتور ویژگی: دو آرگومان می گیرد: شی هدف و نام ویژگی.
- دکوراتور پارامتر: سه آرگومان می گیرد: شی هدف، نام متد و فهرست پارامتر در لیست پارامترهای متد.
در اینجا یک مثال از یک دکوراتور کلاس ساده آورده شده است:
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
در این مثال، دکوراتور @sealed به کلاس Greeter اعمال می شود. تابع sealed هم سازنده و هم نمونه اولیه آن را فریز می کند و از تغییرات بیشتر جلوگیری می کند. این می تواند برای اطمینان از تغییرناپذیری کلاس های خاص مفید باشد.
قدرت بازتاب فراداده
بازتاب فراداده راهی برای دسترسی به فراداده مرتبط با کلاس ها، متدها، ویژگی ها و پارامترها در زمان اجرا فراهم می کند. این امکان قابلیت های قدرتمندی مانند تزریق وابستگی، سریال سازی و اعتبارسنجی را فراهم می کند. جاوا اسکریپت، به خودی خود، ذاتاً از بازتاب به همان شیوه ای که زبان هایی مانند جاوا یا C# پشتیبانی می کنند، پشتیبانی نمی کند. با این حال، کتابخانه هایی مانند reflect-metadata این قابلیت را ارائه می دهند.
کتابخانه reflect-metadata، که توسط ران باکتون توسعه یافته است، به شما امکان می دهد با استفاده از دکوراتورها فراداده را به کلاس ها و اعضای آنها پیوست کنید و سپس این فراداده را در زمان اجرا بازیابی کنید. این به شما امکان می دهد برنامه های انعطاف پذیرتر و قابل تنظیم تری بسازید.
نصب و وارد کردن reflect-metadata
برای استفاده از reflect-metadata، ابتدا باید آن را با استفاده از npm یا yarn نصب کنید:
npm install reflect-metadata --save
یا با استفاده از yarn:
yarn add reflect-metadata
سپس، باید آن را به پروژه خود وارد کنید. در TypeScript، می توانید خط زیر را در بالای فایل اصلی خود (به عنوان مثال، index.ts یا app.ts) اضافه کنید:
import 'reflect-metadata';
این دستور وارد کردن بسیار مهم است زیرا API های ضروری Reflect را که توسط دکوراتورها و بازتاب فراداده استفاده می شوند، پلی فیل می کند. اگر این وارد کردن را فراموش کنید، ممکن است کد شما به درستی کار نکند و احتمالاً با خطاهای زمان اجرا مواجه خواهید شد.
پیوست فراداده با دکوراتورها
کتابخانه reflect-metadata تابع Reflect.defineMetadata را برای پیوست فراداده به اشیاء ارائه می دهد. با این حال، استفاده از دکوراتورها برای تعریف فراداده رایج تر و راحت تر است. کارخانه دکوراتور Reflect.metadata روشی مختصر برای تعریف فراداده با استفاده از دکوراتورها ارائه می دهد.
در اینجا یک مثال آورده شده است:
import 'reflect-metadata';
const formatMetadataKey = Symbol("format");
function format(formatString: string) {
return Reflect.metadata(formatMetadataKey, formatString);
}
function getFormat(target: any, propertyKey: string) {
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
class Example {
@format("Hello, %s")
greeting: string = "World";
greet() {
let formatString = getFormat(this, "greeting");
return formatString.replace("%s", this.greeting);
}
}
let example = new Example();
console.log(example.greet()); // Output: Hello, World
در این مثال، دکوراتور @format برای مرتبط کردن رشته فرمت "Hello, %s" با ویژگی greeting کلاس Example استفاده می شود. تابع getFormat از Reflect.getMetadata برای بازیابی این فراداده در زمان اجرا استفاده می کند. سپس متد greet از این فراداده برای فرمت کردن پیام خوشامدگویی استفاده می کند.
API فراداده Reflect
کتابخانه reflect-metadata چندین تابع برای کار با فراداده ارائه می دهد:
Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey?): فراداده را به یک شی یا ویژگی پیوست می کند.Reflect.getMetadata(metadataKey, target, propertyKey?): فراداده را از یک شی یا ویژگی بازیابی می کند.Reflect.hasMetadata(metadataKey, target, propertyKey?): بررسی می کند که آیا فراداده روی یک شی یا ویژگی وجود دارد یا خیر.Reflect.deleteMetadata(metadataKey, target, propertyKey?): فراداده را از یک شی یا ویژگی حذف می کند.Reflect.getMetadataKeys(target, propertyKey?): آرایه ای از تمام کلیدهای فراداده تعریف شده روی یک شی یا ویژگی را برمی گرداند.Reflect.getOwnMetadataKeys(target, propertyKey?): آرایه ای از تمام کلیدهای فراداده ای که مستقیماً روی یک شی یا ویژگی تعریف شده اند (به استثنای فراداده ارثی) برمی گرداند.
موارد استفاده و مثال های عملی
دکوراتورها و بازتاب فراداده کاربردهای متعددی در توسعه مدرن جاوا اسکریپت دارند. در اینجا چند مثال آورده شده است:
تزریق وابستگی
تزریق وابستگی (DI) یک الگوی طراحی است که با ارائه وابستگی ها به یک کلاس به جای ایجاد آنها توسط خود کلاس، اتصال سست بین اجزا را ترویج می کند. دکوراتورها و بازتاب فراداده می توانند برای پیاده سازی ظروف DI در جاوا اسکریپت استفاده شوند.
سناریویی را در نظر بگیرید که در آن یک UserService دارید که به یک UserRepository وابسته است. می توانید از دکوراتورها برای مشخص کردن وابستگی ها و یک ظرف DI برای حل آنها در زمان اجرا استفاده کنید.
import 'reflect-metadata';
const Injectable = (): ClassDecorator => {
return (target: any) => {
Reflect.defineMetadata('design:paramtypes', [], target);
};
};
const Inject = (token: any): ParameterDecorator => {
return (target: any, propertyKey: string | symbol, parameterIndex: number) => {
let existingParameters: any[] = Reflect.getOwnMetadata('design:paramtypes', target, propertyKey) || [];
existingParameters[parameterIndex] = token;
Reflect.defineMetadata('design:paramtypes', existingParameters, target, propertyKey);
};
};
class UserRepository {
getUsers() {
return ['user1', 'user2'];
}
}
@Injectable()
class UserService {
private userRepository: UserRepository;
constructor(@Inject(UserRepository) userRepository: UserRepository) {
this.userRepository = userRepository;
}
getUsers() {
return this.userRepository.getUsers();
}
}
// Simple DI Container
class Container {
private static dependencies = new Map();
static register(key: any, concrete: { new(...args: any[]): T }): void {
Container.dependencies.set(key, concrete);
}
static resolve(key: any): T {
const concrete = Container.dependencies.get(key);
if (!concrete) {
throw new Error(`No binding found for ${key}`);
}
const paramtypes = Reflect.getMetadata('design:paramtypes', concrete) || [];
const dependencies = paramtypes.map((param: any) => Container.resolve(param));
return new concrete(...dependencies);
}
}
// Register Dependencies
Container.register(UserRepository, UserRepository);
Container.register(UserService, UserService);
// Resolve UserService
const userService = Container.resolve(UserService);
console.log(userService.getUsers()); // Output: ['user1', 'user2']
در این مثال، دکوراتور @Injectable کلاس هایی را که می توانند تزریق شوند، علامت گذاری می کند و دکوراتور @Inject وابستگی های یک سازنده را مشخص می کند. کلاس Container به عنوان یک ظرف DI ساده عمل می کند و وابستگی ها را بر اساس فراداده تعریف شده توسط دکوراتورها حل می کند.
سریال سازی و غیرسریال سازی
دکوراتورها و بازتاب فراداده می توانند برای سفارشی کردن فرآیند سریال سازی و غیرسریال سازی اشیاء استفاده شوند. این می تواند برای نگاشت اشیاء به فرمت های مختلف داده، مانند JSON یا XML، یا برای اعتبارسنجی داده ها قبل از غیرسریال سازی مفید باشد.
سناریویی را در نظر بگیرید که می خواهید یک کلاس را به JSON سریال کنید، اما می خواهید ویژگی های خاصی را حذف یا تغییر نام دهید. می توانید از دکوراتورها برای مشخص کردن قوانین سریال سازی استفاده کنید و سپس از فراداده برای انجام سریال سازی استفاده کنید.
import 'reflect-metadata';
const Exclude = (): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('serialize:exclude', true, target, propertyKey);
};
};
const Rename = (newName: string): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('serialize:rename', newName, target, propertyKey);
};
};
class User {
@Exclude()
id: number;
@Rename('fullName')
name: string;
email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
}
function serialize(obj: any): string {
const serialized: any = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const exclude = Reflect.getMetadata('serialize:exclude', obj, key);
if (exclude) {
continue;
}
const rename = Reflect.getMetadata('serialize:rename', obj, key);
const newKey = rename || key;
serialized[newKey] = obj[key];
}
}
return JSON.stringify(serialized);
}
const user = new User(1, 'John Doe', 'john.doe@example.com');
const serializedUser = serialize(user);
console.log(serializedUser); // Output: {"fullName":"John Doe","email":"john.doe@example.com"}
در این مثال، دکوراتور @Exclude ویژگی id را به عنوان حذف شده از سریال سازی علامت گذاری می کند و دکوراتور @Rename نام ویژگی name را به fullName تغییر می دهد. تابع serialize از فراداده برای انجام سریال سازی مطابق با قوانین تعریف شده استفاده می کند.
اعتبارسنجی
دکوراتورها و بازتاب فراداده می توانند برای پیاده سازی منطق اعتبارسنجی برای کلاس ها و ویژگی ها استفاده شوند. این می تواند برای اطمینان از اینکه داده ها قبل از پردازش یا ذخیره سازی معیارهای خاصی را برآورده می کنند، مفید باشد.
سناریویی را در نظر بگیرید که می خواهید اعتبارسنجی کنید که یک ویژگی خالی نیست یا با یک عبارت منظم خاص مطابقت دارد. می توانید از دکوراتورها برای مشخص کردن قوانین اعتبارسنجی استفاده کنید و سپس از فراداده برای انجام اعتبارسنجی استفاده کنید.
import 'reflect-metadata';
const Required = (): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('validate:required', true, target, propertyKey);
};
};
const Pattern = (regex: RegExp): PropertyDecorator => {
return (target: any, propertyKey: string | symbol) => {
Reflect.defineMetadata('validate:pattern', regex, target, propertyKey);
};
};
class Product {
@Required()
name: string;
@Pattern(/^\d+$/)
price: string;
constructor(name: string, price: string) {
this.name = name;
this.price = price;
}
}
function validate(obj: any): string[] {
const errors: string[] = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const required = Reflect.getMetadata('validate:required', obj, key);
if (required && !obj[key]) {
errors.push(`${key} is required`);
}
const pattern = Reflect.getMetadata('validate:pattern', obj, key);
if (pattern && !pattern.test(obj[key])) {
errors.push(`${key} must match ${pattern}`);
}
}
}
return errors;
}
const product = new Product('', 'abc');
const errors = validate(product);
console.log(errors); // Output: ["name is required", "price must match /^\d+$/"]
در این مثال، دکوراتور @Required ویژگی name را به عنوان الزامی علامت گذاری می کند و دکوراتور @Pattern یک عبارت منظم را مشخص می کند که ویژگی price باید با آن مطابقت داشته باشد. تابع validate از فراداده برای انجام اعتبارسنجی استفاده می کند و آرایه ای از خطاها را برمی گرداند.
AOP (برنامه نویسی جنبه گرا)
AOP یک پارادایم برنامه نویسی است که هدف آن افزایش مدولار بودن با اجازه دادن به جداسازی نگرانی های متقابل است. دکوراتورها به طور طبیعی خود را به سناریوهای AOP قرض می دهند. به عنوان مثال، بررسی های ثبت وقایع، ممیزی و امنیتی را می توان به عنوان دکوراتور پیاده سازی کرد و بدون تغییر منطق اصلی متد، به متدها اعمال کرد.
مثال: پیاده سازی یک جنبه ثبت وقایع با استفاده از دکوراتورها.
import 'reflect-metadata';
function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Entering method: ${propertyKey} with arguments: ${JSON.stringify(args)}`);
const result = originalMethod.apply(this, args);
console.log(`Exiting method: ${propertyKey} with result: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@LogMethod
add(a: number, b: number): number {
return a + b;
}
@LogMethod
subtract(a: number, b: number): number {
return a - b;
}
}
const calculator = new Calculator();
calculator.add(5, 3);
calculator.subtract(10, 2);
// Output:
// Entering method: add with arguments: [5,3]
// Exiting method: add with result: 8
// Entering method: subtract with arguments: [10,2]
// Exiting method: subtract with result: 8
این کد نقاط ورود و خروج متدهای add و subtract را ثبت می کند و به طور موثر نگرانی ثبت وقایع را از عملکرد اصلی ماشین حساب جدا می کند.
مزایای استفاده از دکوراتورها و بازتاب فراداده
استفاده از دکوراتورها و بازتاب فراداده در جاوا اسکریپت چندین مزیت دارد:
- بهبود قابلیت خوانایی کد: دکوراتورها روشی مختصر و اعلانی برای تغییر یا گسترش رفتار کلاس ها و اعضای آنها ارائه می دهند و کد را آسان تر برای خواندن و درک می کنند.
- افزایش مدولار بودن: دکوراتورها جداسازی نگرانی ها را ترویج می کنند و به شما امکان می دهند نگرانی های متقابل را ایزوله کنید و از تکرار کد جلوگیری کنید.
- افزایش قابلیت نگهداری: با جداسازی نگرانی ها و کاهش تکرار کد، دکوراتورها نگهداری و به روز رسانی کد را آسان تر می کنند.
- انعطاف پذیری بیشتر: بازتاب فراداده به شما امکان می دهد در زمان اجرا به فراداده دسترسی داشته باشید و به شما امکان می دهد برنامه های انعطاف پذیرتر و قابل تنظیم تری بسازید.
- فعال سازی AOP: دکوراتورها AOP را با اجازه دادن به شما برای اعمال جنبه ها به متدها بدون تغییر منطق اصلی آنها تسهیل می کنند.
چالش ها و ملاحظات
در حالی که دکوراتورها و بازتاب فراداده مزایای متعددی را ارائه می دهند، چالش ها و ملاحظاتی نیز وجود دارد که باید در نظر داشت:
- سربار عملکرد: بازتاب فراداده می تواند سربار عملکردی ایجاد کند، به خصوص اگر به طور گسترده استفاده شود.
- پیچیدگی: درک و استفاده از دکوراتورها و بازتاب فراداده نیاز به درک عمیق تری از جاوا اسکریپت و کتابخانه
reflect-metadataدارد. - اشکال زدایی: اشکال زدایی کدی که از دکوراتورها و بازتاب فراداده استفاده می کند می تواند چالش برانگیزتر از اشکال زدایی کد سنتی باشد.
- سازگاری: دکوراتورها هنوز یک پیشنهاد مرحله 2 ECMAScript هستند و پیاده سازی آنها ممکن است در محیط های مختلف جاوا اسکریپت متفاوت باشد. TypeScript پشتیبانی عالی ارائه می دهد، اما به خاطر داشته باشید که پلی فیل زمان اجرا ضروری است.
بهترین شیوه ها
برای استفاده موثر از دکوراتورها و بازتاب فراداده، بهترین شیوه های زیر را در نظر بگیرید:
- از دکوراتورها به طور کم استفاده کنید: فقط زمانی از دکوراتورها استفاده کنید که مزیت آشکاری از نظر قابلیت خوانایی، مدولار بودن یا قابلیت نگهداری کد ارائه دهند. از استفاده بیش از حد از دکوراتورها خودداری کنید، زیرا می توانند کد را پیچیده تر و اشکال زدایی آن را سخت تر کنند.
- دکوراتورها را ساده نگه دارید: دکوراتورها را بر یک مسئولیت واحد متمرکز کنید. از ایجاد دکوراتورهای پیچیده ای که چندین کار را انجام می دهند خودداری کنید.
- مستندسازی دکوراتورها: هدف و کاربرد هر دکوراتور را به وضوح مستند کنید. این کار درک و استفاده از کد شما را برای سایر توسعه دهندگان آسان تر می کند.
- آزمایش کامل دکوراتورها: دکوراتورهای خود را به طور کامل آزمایش کنید تا مطمئن شوید که به درستی کار می کنند و هیچ گونه عوارض جانبی غیرمنتظره ای ایجاد نمی کنند.
- استفاده از یک قرارداد نامگذاری ثابت: یک قرارداد نامگذاری ثابت برای دکوراتورها اتخاذ کنید تا قابلیت خوانایی کد را بهبود ببخشید. به عنوان مثال، می توانید تمام نام های دکوراتور را با
@پیشوند کنید.
جایگزین های دکوراتورها
در حالی که دکوراتورها مکانیسم قدرتمندی برای افزودن عملکرد به کلاس ها و متدها ارائه می دهند، رویکردهای جایگزینی وجود دارند که می توانند در شرایطی که دکوراتورها در دسترس یا مناسب نیستند، استفاده شوند.
توابع مرتبه بالاتر
توابع مرتبه بالاتر (HOF) توابعی هستند که توابع دیگر را به عنوان آرگومان می گیرند یا توابع را به عنوان نتیجه برمی گردانند. HOF ها می توانند برای پیاده سازی بسیاری از الگوهای مشابه دکوراتورها، مانند ثبت وقایع، اعتبارسنجی و مجوز استفاده شوند.
میکس این ها
میکس این ها راهی برای افزودن عملکرد به کلاس ها با ترکیب آنها با کلاس های دیگر هستند. میکس این ها می توانند برای به اشتراک گذاشتن کد بین چندین کلاس و جلوگیری از تکرار کد استفاده شوند.
Monkey Patching
Monkey patching عمل تغییر رفتار کد موجود در زمان اجرا است. Monkey patching می تواند برای افزودن عملکرد به کلاس ها و متدها بدون تغییر کد منبع آنها استفاده شود. با این حال، monkey patching می تواند خطرناک باشد و باید با احتیاط استفاده شود، زیرا می تواند منجر به عوارض جانبی غیرمنتظره شود و نگهداری کد را سخت تر کند.
نتیجه گیری
دکوراتورهای جاوا اسکریپت، همراه با بازتاب فراداده، مجموعه ای قدرتمند از ابزارها را برای افزایش مدولار بودن، قابلیت نگهداری و انعطاف پذیری کد ارائه می دهند. آنها با فعال کردن دسترسی به فراداده در زمان اجرا، قابلیت های پیشرفته ای مانند تزریق وابستگی، سریال سازی، اعتبارسنجی و AOP را باز می کنند. در حالی که چالش هایی برای در نظر گرفتن وجود دارد، مانند سربار عملکرد و پیچیدگی، مزایای استفاده از دکوراتورها و بازتاب فراداده اغلب بیشتر از معایب است. با پیروی از بهترین شیوه ها و درک جایگزین ها، توسعه دهندگان می توانند به طور موثر از این تکنیک ها برای ساخت برنامه های جاوا اسکریپت قوی تر و مقیاس پذیرتر استفاده کنند. با ادامه تکامل جاوا اسکریپت، دکوراتورها و بازتاب فراداده احتمالاً برای مدیریت پیچیدگی و ترویج استفاده مجدد از کد در توسعه وب مدرن اهمیت بیشتری پیدا می کنند.
این مقاله یک نمای کلی جامع از دکوراتورهای جاوا اسکریپت، فراداده و بازتاب ارائه می دهد و نحو، موارد استفاده و بهترین شیوه ها را پوشش می دهد. با درک این مفاهیم، توسعه دهندگان می توانند پتانسیل کامل جاوا اسکریپت را باز کنند و برنامه های قدرتمندتر و قابل نگهداری تری بسازند.
با پذیرش این تکنیکها، توسعهدهندگان در سرتاسر جهان میتوانند به یک اکوسیستم جاوا اسکریپت مدولارتر، قابل نگهداریتر و مقیاسپذیرتر کمک کنند.