ऑब्जेक्ट व्यवहार संशोधन के लिए जावास्क्रिप्ट प्रॉक्सी पैटर्न का अन्वेषण करें। कोड उदाहरणों के साथ सत्यापन, वर्चुअलाइजेशन, ट्रैकिंग और अन्य उन्नत तकनीकों के बारे में जानें।
जावास्क्रिप्ट प्रॉक्सी पैटर्न: ऑब्जेक्ट व्यवहार संशोधन में महारत हासिल करना
जावास्क्रिप्ट प्रॉक्सी ऑब्जेक्ट, ऑब्जेक्ट्स पर मूलभूत ऑपरेशनों को रोकने और अनुकूलित करने के लिए एक शक्तिशाली तंत्र प्रदान करता है। यह क्षमता ऑब्जेक्ट व्यवहार को नियंत्रित करने के लिए डिज़ाइन पैटर्न और उन्नत तकनीकों की एक विस्तृत श्रृंखला के द्वार खोलती है। यह व्यापक गाइड विभिन्न प्रॉक्सी पैटर्न की खोज करता है, व्यावहारिक कोड उदाहरणों के साथ उनके उपयोगों को दर्शाता है।
जावास्क्रिप्ट प्रॉक्सी क्या है?
एक प्रॉक्सी ऑब्जेक्ट दूसरे ऑब्जेक्ट (लक्ष्य) को लपेटता है और उसके ऑपरेशनों को रोकता है। इन ऑपरेशनों, जिन्हें ट्रैप के रूप में जाना जाता है, में प्रॉपर्टी लुकअप, असाइनमेंट, एन्यूमरेशन और फंक्शन इनवोकेशन शामिल हैं। प्रॉक्सी आपको इन ऑपरेशनों से पहले, बाद में, या उनके बजाय निष्पादित करने के लिए कस्टम लॉजिक को परिभाषित करने की अनुमति देता है। प्रॉक्सी की मूल अवधारणा में "मेटाप्रोग्रामिंग" शामिल है जो आपको जावास्क्रिप्ट भाषा के व्यवहार में हेरफेर करने में सक्षम बनाती है।
प्रॉक्सी बनाने का मूल सिंटैक्स है:
const proxy = new Proxy(target, handler);
- target: वह मूल ऑब्जेक्ट जिसे आप प्रॉक्सी करना चाहते हैं।
- handler: एक ऑब्जेक्ट जिसमें विधियाँ (ट्रैप्स) होती हैं जो परिभाषित करती हैं कि प्रॉक्सी लक्ष्य पर संचालन को कैसे रोकता है।
सामान्य प्रॉक्सी ट्रैप्स
हैंडलर ऑब्जेक्ट कई ट्रैप्स को परिभाषित कर सकता है। यहाँ कुछ सबसे अधिक उपयोग किए जाने वाले ट्रैप्स हैं:
- get(target, property, receiver): प्रॉपर्टी एक्सेस को रोकता है (जैसे,
obj.property
)। - set(target, property, value, receiver): प्रॉपर्टी असाइनमेंट को रोकता है (जैसे,
obj.property = value
)। - has(target, property):
in
ऑपरेटर को रोकता है (जैसे,'property' in obj
)। - deleteProperty(target, property):
delete
ऑपरेटर को रोकता है (जैसे,delete obj.property
)। - apply(target, thisArg, argumentsList): फ़ंक्शन कॉल्स को रोकता है (जब लक्ष्य एक फ़ंक्शन होता है)।
- construct(target, argumentsList, newTarget):
new
ऑपरेटर को रोकता है (जब लक्ष्य एक कंस्ट्रक्टर फ़ंक्शन होता है)। - getPrototypeOf(target):
Object.getPrototypeOf()
के कॉल्स को रोकता है। - setPrototypeOf(target, prototype):
Object.setPrototypeOf()
के कॉल्स को रोकता है। - isExtensible(target):
Object.isExtensible()
के कॉल्स को रोकता है। - preventExtensions(target):
Object.preventExtensions()
के कॉल्स को रोकता है। - getOwnPropertyDescriptor(target, property):
Object.getOwnPropertyDescriptor()
के कॉल्स को रोकता है। - defineProperty(target, property, descriptor):
Object.defineProperty()
के कॉल्स को रोकता है। - ownKeys(target):
Object.getOwnPropertyNames()
औरObject.getOwnPropertySymbols()
के कॉल्स को रोकता है।
प्रॉक्सी पैटर्न और उपयोग के मामले
आइए कुछ सामान्य प्रॉक्सी पैटर्न और उन्हें वास्तविक दुनिया के परिदृश्यों में कैसे लागू किया जा सकता है, इसका पता लगाएं:
1. सत्यापन (Validation)
सत्यापन पैटर्न प्रॉपर्टी असाइनमेंट पर बाधाओं को लागू करने के लिए एक प्रॉक्सी का उपयोग करता है। यह डेटा की अखंडता सुनिश्चित करने के लिए उपयोगी है।
const validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('Age is not an integer');
}
if (value < 0) {
throw new RangeError('Age must be a non-negative integer');
}
}
// मान संग्रहीत करने के लिए डिफ़ॉल्ट व्यवहार
obj[prop] = value;
// सफलता इंगित करें
return true;
}
};
let person = {};
let proxy = new Proxy(person, validator);
proxy.age = 25; // मान्य
console.log(proxy.age); // आउटपुट: 25
try {
proxy.age = 'young'; // TypeError फेंकता है
} catch (e) {
console.log(e); // आउटपुट: TypeError: Age is not an integer
}
try {
proxy.age = -10; // RangeError फेंकता है
} catch (e) {
console.log(e); // आउटपुट: RangeError: Age must be a non-negative integer
}
उदाहरण: एक ई-कॉमर्स प्लेटफॉर्म पर विचार करें जहां उपयोगकर्ता डेटा को सत्यापन की आवश्यकता होती है। एक प्रॉक्सी उम्र, ईमेल प्रारूप, पासवर्ड की मजबूती और अन्य क्षेत्रों पर नियम लागू कर सकता है, जिससे अमान्य डेटा को संग्रहीत होने से रोका जा सकता है।
2. वर्चुअलाइजेशन (लेजी लोडिंग)
वर्चुअलाइजेशन, जिसे लेजी लोडिंग के रूप में भी जाना जाता है, महंगे संसाधनों की लोडिंग में तब तक देरी करता है जब तक कि उनकी वास्तव में आवश्यकता न हो। एक प्रॉक्सी वास्तविक ऑब्जेक्ट के लिए एक प्लेसहोल्डर के रूप-रंग में काम कर सकता है, इसे केवल तभी लोड करता है जब किसी प्रॉपर्टी तक पहुँचा जाता है।
const expensiveData = {
load: function() {
console.log('Loading expensive data...');
// एक समय लेने वाले ऑपरेशन का अनुकरण करें (जैसे, डेटाबेस से लाना)
return new Promise(resolve => {
setTimeout(() => {
resolve({
data: 'This is the expensive data'
});
}, 2000);
});
}
};
const lazyLoadHandler = {
get: function(target, prop) {
if (prop === 'data') {
console.log('Accessing data, loading it if necessary...');
return target.load().then(result => {
target.data = result.data; // लोड किए गए डेटा को स्टोर करें
return result.data;
});
} else {
return target[prop];
}
}
};
const lazyData = new Proxy(expensiveData, lazyLoadHandler);
console.log('Initial access...');
lazyData.data.then(data => {
console.log('Data:', data); // आउटपुट: Data: This is the expensive data
});
console.log('Subsequent access...');
lazyData.data.then(data => {
console.log('Data:', data); // आउटपुट: Data: This is the expensive data (कैश से लोड किया गया)
});
उदाहरण: एक बड़े सोशल मीडिया प्लेटफॉर्म की कल्पना करें जिसमें उपयोगकर्ता प्रोफाइल में कई विवरण और संबंधित मीडिया शामिल हों। सभी प्रोफाइल डेटा को तुरंत लोड करना अक्षम हो सकता है। एक प्रॉक्सी के साथ वर्चुअलाइजेशन पहले बुनियादी प्रोफाइल जानकारी लोड करने की अनुमति देता है, और फिर अतिरिक्त विवरण या मीडिया सामग्री को केवल तभी लोड करता है जब उपयोगकर्ता उन अनुभागों पर नेविगेट करता है।
3. लॉगिंग और ट्रैकिंग
प्रॉक्सी का उपयोग प्रॉपर्टी एक्सेस और संशोधनों को ट्रैक करने के लिए किया जा सकता है। यह डिबगिंग, ऑडिटिंग और प्रदर्शन निगरानी के लिए मूल्यवान है।
const logHandler = {
get: function(target, prop, receiver) {
console.log(`GET ${prop}`);
return Reflect.get(target, prop, receiver);
},
set: function(target, prop, value) {
console.log(`SET ${prop} to ${value}`);
target[prop] = value;
return true;
}
};
let obj = { name: 'Alice' };
let proxy = new Proxy(obj, logHandler);
console.log(proxy.name); // आउटपुट: GET name, Alice
proxy.age = 30; // आउटपुट: SET age to 30
उदाहरण: एक सहयोगी दस्तावेज़ संपादन एप्लिकेशन में, एक प्रॉक्सी दस्तावेज़ सामग्री में किए गए हर बदलाव को ट्रैक कर सकता है। यह एक ऑडिट ट्रेल बनाने, पूर्ववत/फिर से करें कार्यक्षमता को सक्षम करने और उपयोगकर्ता योगदान में अंतर्दृष्टि प्रदान करने की अनुमति देता है।
4. केवल-पढ़ने योग्य दृश्य (Read-Only Views)
प्रॉक्सी ऑब्जेक्ट्स के केवल-पढ़ने योग्य दृश्य बना सकते हैं, जो आकस्मिक संशोधनों को रोकते हैं। यह संवेदनशील डेटा की सुरक्षा के लिए उपयोगी है।
const readOnlyHandler = {
set: function(target, prop, value) {
console.error(`Cannot set property ${prop}: object is read-only`);
return false; // इंगित करें कि सेट ऑपरेशन विफल हो गया
},
deleteProperty: function(target, prop) {
console.error(`Cannot delete property ${prop}: object is read-only`);
return false; // इंगित करें कि डिलीट ऑपरेशन विफल हो गया
}
};
let data = { name: 'Bob', age: 40 };
let readOnlyData = new Proxy(data, readOnlyHandler);
try {
readOnlyData.age = 41; // एक त्रुटि फेंकता है
} catch (e) {
console.log(e); // कोई त्रुटि नहीं फेंकी गई क्योंकि 'set' ट्रैप false लौटाता है।
}
try {
delete readOnlyData.name; // एक त्रुटि फेंकता है
} catch (e) {
console.log(e); // कोई त्रुटि नहीं फेंकी गई क्योंकि 'deleteProperty' ट्रैप false लौटाता है।
}
console.log(data.age); // आउटपुट: 40 (अपरिवर्तित)
उदाहरण: एक वित्तीय प्रणाली पर विचार करें जहां कुछ उपयोगकर्ताओं के पास खाते की जानकारी तक केवल-पढ़ने योग्य पहुंच होती है। एक प्रॉक्सी का उपयोग इन उपयोगकर्ताओं को खाते की शेष राशि या अन्य महत्वपूर्ण डेटा को संशोधित करने से रोकने के लिए किया जा सकता है।
5. डिफ़ॉल्ट मान (Default Values)
एक प्रॉक्सी अनुपलब्ध गुणों के लिए डिफ़ॉल्ट मान प्रदान कर सकता है। यह कोड को सरल बनाता है और null/undefined जाँचों से बचाता है।
const defaultValuesHandler = {
get: function(target, prop, receiver) {
if (!(prop in target)) {
console.log(`Property ${prop} not found, returning default value.`);
return 'Default Value'; // या कोई अन्य उपयुक्त डिफ़ॉल्ट
}
return Reflect.get(target, prop, receiver);
}
};
let config = { apiUrl: 'https://api.example.com' };
let configWithDefaults = new Proxy(config, defaultValuesHandler);
console.log(configWithDefaults.apiUrl); // आउटपुट: https://api.example.com
console.log(configWithDefaults.timeout); // आउटपुट: Property timeout not found, returning default value. Default Value
उदाहरण: एक कॉन्फ़िगरेशन प्रबंधन प्रणाली में, एक प्रॉक्सी अनुपलब्ध सेटिंग्स के लिए डिफ़ॉल्ट मान प्रदान कर सकता है। उदाहरण के लिए, यदि कोई कॉन्फ़िगरेशन फ़ाइल डेटाबेस कनेक्शन टाइमआउट निर्दिष्ट नहीं करती है, तो प्रॉक्सी एक पूर्वनिर्धारित डिफ़ॉल्ट मान लौटा सकता है।
6. मेटाडेटा और एनोटेशन
प्रॉक्सी ऑब्जेक्ट्स में मेटाडेटा या एनोटेशन संलग्न कर सकते हैं, जो मूल ऑब्जेक्ट को संशोधित किए बिना अतिरिक्त जानकारी प्रदान करते हैं।
const metadataHandler = {
get: function(target, prop, receiver) {
if (prop === '__metadata__') {
return { description: 'This is metadata for the object' };
}
return Reflect.get(target, prop, receiver);
}
};
let article = { title: 'Introduction to Proxies', content: '...' };
let articleWithMetadata = new Proxy(article, metadataHandler);
console.log(articleWithMetadata.title); // आउटपुट: Introduction to Proxies
console.log(articleWithMetadata.__metadata__.description); // आउटपुट: This is metadata for the object
उदाहरण: एक सामग्री प्रबंधन प्रणाली में, एक प्रॉक्सी लेखों में मेटाडेटा संलग्न कर सकता है, जैसे लेखक की जानकारी, प्रकाशन की तारीख और कीवर्ड। इस मेटाडेटा का उपयोग सामग्री को खोजने, फ़िल्टर करने और वर्गीकृत करने के लिए किया जा सकता है।
7. फ़ंक्शन इंटरसेप्शन
प्रॉक्सी फ़ंक्शन कॉल्स को रोक सकते हैं, जिससे आप लॉगिंग, सत्यापन, या अन्य प्री- या पोस्ट-प्रोसेसिंग लॉजिक जोड़ सकते हैं।
const functionInterceptor = {
apply: function(target, thisArg, argumentsList) {
console.log('Calling function with arguments:', argumentsList);
const result = target.apply(thisArg, argumentsList);
console.log('Function returned:', result);
return result;
}
};
function add(a, b) {
return a + b;
}
let proxiedAdd = new Proxy(add, functionInterceptor);
let sum = proxiedAdd(5, 3); // आउटपुट: Calling function with arguments: [5, 3], Function returned: 8
console.log(sum); // आउटपुट: 8
उदाहरण: एक बैंकिंग एप्लिकेशन में, एक प्रॉक्सी लेनदेन फ़ंक्शनों के कॉल्स को रोक सकता है, प्रत्येक लेनदेन को लॉग कर सकता है और लेनदेन को निष्पादित करने से पहले धोखाधड़ी का पता लगाने की जाँच कर सकता है।
8. कंस्ट्रक्टर इंटरसेप्शन
प्रॉक्सी कंस्ट्रक्टर कॉल्स को रोक सकते हैं, जिससे आप ऑब्जेक्ट निर्माण को अनुकूलित कर सकते हैं।
const constructorInterceptor = {
construct: function(target, argumentsList, newTarget) {
console.log('Creating a new instance of', target.name, 'with arguments:', argumentsList);
const obj = new target(...argumentsList);
console.log('New instance created:', obj);
return obj;
}
};
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
let ProxiedPerson = new Proxy(Person, constructorInterceptor);
let person = new ProxiedPerson('Alice', 28); // आउटपुट: Creating a new instance of Person with arguments: ['Alice', 28], New instance created: Person { name: 'Alice', age: 28 }
console.log(person);
उदाहरण: एक गेम डेवलपमेंट फ्रेमवर्क में, एक प्रॉक्सी गेम ऑब्जेक्ट्स के निर्माण को रोक सकता है, स्वचालित रूप से अद्वितीय आईडी असाइन कर सकता है, डिफ़ॉल्ट कंपोनेंट्स जोड़ सकता है, और उन्हें गेम इंजन के साथ पंजीकृत कर सकता है।
उन्नत विचार
- प्रदर्शन: जबकि प्रॉक्सी लचीलापन प्रदान करते हैं, वे प्रदर्शन ओवरहेड का कारण बन सकते हैं। अपने कोड का बेंचमार्क और प्रोफाइल करना महत्वपूर्ण है ताकि यह सुनिश्चित हो सके कि प्रॉक्सी का उपयोग करने के लाभ प्रदर्शन लागत से अधिक हैं, विशेष रूप से प्रदर्शन-महत्वपूर्ण अनुप्रयोगों में।
- संगतता: प्रॉक्सी जावास्क्रिप्ट में एक अपेक्षाकृत हालिया সংযোজন हैं, इसलिए पुराने ब्राउज़र उनका समर्थन नहीं कर सकते हैं। पुराने वातावरण के साथ संगतता सुनिश्चित करने के लिए फ़ीचर डिटेक्शन या पॉलीफ़िल्स का उपयोग करें।
- निरस्त करने योग्य प्रॉक्सी (Revocable Proxies):
Proxy.revocable()
विधि एक प्रॉक्सी बनाती है जिसे निरस्त किया जा सकता है। प्रॉक्सी को निरस्त करने से किसी भी आगे के संचालन को बाधित होने से रोका जा सकता है। यह सुरक्षा या संसाधन प्रबंधन उद्देश्यों के लिए उपयोगी हो सकता है। - रिफ्लेक्ट एपीआई (Reflect API): रिफ्लेक्ट एपीआई प्रॉक्सी ट्रैप के डिफ़ॉल्ट व्यवहार को करने के लिए विधियाँ प्रदान करता है।
Reflect
का उपयोग यह सुनिश्चित करता है कि आपका प्रॉक्सी कोड भाषा विनिर्देश के अनुरूप व्यवहार करता है।
निष्कर्ष
जावास्क्रिप्ट प्रॉक्सी ऑब्जेक्ट व्यवहार को अनुकूलित करने के लिए एक शक्तिशाली और बहुमुखी तंत्र प्रदान करते हैं। विभिन्न प्रॉक्सी पैटर्न में महारत हासिल करके, आप अधिक मजबूत, रखरखाव योग्य और कुशल कोड लिख सकते हैं। चाहे आप सत्यापन, वर्चुअलाइजेशन, ट्रैकिंग, या अन्य उन्नत तकनीकों को लागू कर रहे हों, प्रॉक्सी ऑब्जेक्ट्स तक पहुंचने और उनमें हेरफेर करने के तरीके को नियंत्रित करने के लिए एक लचीला समाधान प्रदान करते हैं। हमेशा प्रदर्शन के प्रभावों पर विचार करें और अपने लक्षित परिवेशों के साथ संगतता सुनिश्चित करें। प्रॉक्सी आधुनिक जावास्क्रिप्ट डेवलपर के शस्त्रागार में एक प्रमुख उपकरण हैं, जो शक्तिशाली मेटाप्रोग्रामिंग तकनीकों को सक्षम करते हैं।
आगे की खोज
- मोज़िला डेवलपर नेटवर्क (MDN): जावास्क्रिप्ट प्रॉक्सी
- जावास्क्रिप्ट प्रॉक्सी की खोज: स्मैशिंग मैगज़ीन लेख