ஜாவாஸ்கிரிப்ட் ப்ராக்ஸி ஏபிஐ-ஐ முழுமையாகக் கற்றுக்கொள்ள உலகளாவிய டெவலப்பர்களுக்கான ஒரு விரிவான வழிகாட்டி. நடைமுறை எடுத்துக்காட்டுகள் மற்றும் செயல்திறன் குறிப்புகளுடன் ஆப்ஜெக்ட் செயல்பாடுகளை இடைமறித்து தனிப்பயனாக்க கற்றுக்கொள்ளுங்கள்.
ஜாவாஸ்கிரிப்ட் ப்ராக்ஸி ஏபிஐ: ஆப்ஜெக்ட் நடத்தையை மாற்றுவதில் ஒரு ஆழமான பார்வை
நவீன ஜாவாஸ்கிரிப்ட்டின் வளர்ந்து வரும் சூழலில், டெவலப்பர்கள் தரவை நிர்வகிக்கவும் அதனுடன் தொடர்பு கொள்ளவும் மிகவும் சக்திவாய்ந்த மற்றும் நேர்த்தியான வழிகளைத் தொடர்ந்து தேடுகின்றனர். கிளாஸ்கள், மாட்யூல்கள், மற்றும் async/await போன்ற அம்சங்கள் நாம் குறியீடு எழுதும் முறையைப் புரட்டிப் போட்டிருந்தாலும், ECMAScript 2015 (ES6) இல் அறிமுகப்படுத்தப்பட்ட ஒரு சக்திவாய்ந்த மெட்டாபுரோகிராமிங் அம்சம் பெரும்பாலும் குறைவாகவே பயன்படுத்தப்படுகிறது: அதுதான் ப்ராக்ஸி ஏபிஐ.
மெட்டாபுரோகிராமிங் என்பது அச்சுறுத்தலாகத் தோன்றலாம், ஆனால் அது மற்ற குறியீடுகளில் செயல்படும் குறியீட்டை எழுதும் ஒரு எளிய கருத்தாகும். ப்ராக்ஸி ஏபிஐ என்பது இதற்கான ஜாவாஸ்கிரிப்ட்டின் முதன்மை கருவியாகும், இது மற்றொரு ஆப்ஜெக்டிற்கு ஒரு 'ப்ராக்ஸி'யை உருவாக்க உங்களை அனுமதிக்கிறது, இது அந்த ஆப்ஜெக்ட்டின் அடிப்படை செயல்பாடுகளை இடைமறித்து மறுவரையறை செய்ய முடியும். இது ஒரு ஆப்ஜெக்ட்டின் முன்னால் ஒரு தனிப்பயனாக்கக்கூடிய வாயிற்காப்பாளரை வைப்பது போன்றது, அது எவ்வாறு அணுகப்படுகிறது மற்றும் மாற்றியமைக்கப்படுகிறது என்பதன் மீது உங்களுக்கு முழுமையான கட்டுப்பாட்டைக் கொடுக்கிறது.
இந்த விரிவான வழிகாட்டி ப்ராக்ஸி ஏபிஐ-ஐப் பற்றிய மர்மங்களைத் தீர்க்கும். நாம் அதன் முக்கிய கருத்துக்களை ஆராய்வோம், அதன் பல்வேறு திறன்களை நடைமுறை எடுத்துக்காட்டுகளுடன் பிரித்து அலசுவோம், மேலும் மேம்பட்ட பயன்பாட்டு வழக்குகள் மற்றும் செயல்திறன் பரிசீலனைகளைப் பற்றி விவாதிப்போம். இதன் முடிவில், ப்ராக்ஸிகள் ஏன் நவீன கட்டமைப்புகளின் மூலக்கல்லாக இருக்கின்றன என்பதையும், அவற்றை நீங்கள் எப்படிப் பயன்படுத்தி சுத்தமான, சக்திவாய்ந்த, மற்றும் பராமரிக்க எளிதான குறியீட்டை எழுதலாம் என்பதையும் புரிந்துகொள்வீர்கள்.
முக்கிய கருத்துக்களைப் புரிந்துகொள்ளுதல்: டார்கெட், ஹேண்ட்லர், மற்றும் ட்ராப்ஸ்
ப்ராக்ஸி ஏபிஐ மூன்று அடிப்படைக் கூறுகளைக் கொண்டுள்ளது. அவற்றின் பங்குகளைப் புரிந்துகொள்வதே ப்ராக்ஸிகளில் தேர்ச்சி பெறுவதற்கான திறவுகோல் ஆகும்.
- டார்கெட் (Target): இது நீங்கள் உறையிட விரும்பும் அசல் ஆப்ஜெக்ட் ஆகும். இது அணிகள், செயல்பாடுகள் அல்லது மற்றொரு ப்ராக்ஸி உட்பட எந்த வகையான ஆப்ஜெக்ட்டாகவும் இருக்கலாம். ப்ராக்ஸி இந்த டார்கெட்டை மெய்நிகராக்குகிறது, மேலும் அனைத்து செயல்பாடுகளும் இறுதியில் (கட்டாயமில்லை என்றாலும்) அதற்கே அனுப்பப்படும்.
- ஹேண்ட்லர் (Handler): இது ப்ராக்ஸிக்கான தர்க்கத்தைக் கொண்ட ஒரு ஆப்ஜெக்ட் ஆகும். இது 'ட்ராப்ஸ்' என்று அழைக்கப்படும் செயல்பாடுகளை பண்புகளாகக் கொண்ட ஒரு ஒதுக்கிட ஆப்ஜெக்ட் ஆகும். ப்ராக்ஸியில் ஒரு செயல்பாடு நிகழும்போது, அது ஹேண்ட்லரில் அதனுடன் தொடர்புடைய ட்ராப்பைத் தேடும்.
- ட்ராப்ஸ் (Traps): இவை ஹேண்ட்லரில் உள்ள பண்பு அணுகலை வழங்கும் முறைகள் ஆகும். ஒவ்வொரு ட்ராப்பும் ஒரு அடிப்படை ஆப்ஜெக்ட் செயல்பாட்டுடன் தொடர்புடையது. எடுத்துக்காட்டாக,
get
ட்ராப் பண்பு வாசிப்பை இடைமறிக்கிறது, மேலும்set
ட்ராப் பண்பு எழுதுதலை இடைமறிக்கிறது. ஹேண்ட்லரில் ஒரு ட்ராப் வரையறுக்கப்படவில்லை என்றால், செயல்பாடு ப்ராக்ஸி இல்லாதது போல் டார்கெட்டிற்கு அனுப்பப்படும்.
ஒரு ப்ராக்ஸியை உருவாக்குவதற்கான தொடரியல் நேரடியானது:
const proxy = new Proxy(target, handler);
ஒரு மிக அடிப்படையான எடுத்துக்காட்டைப் பார்ப்போம். ஒரு காலி ஹேண்ட்லரைப் பயன்படுத்தி அனைத்து செயல்பாடுகளையும் டார்கெட் ஆப்ஜெக்ட்டிற்கு அனுப்பும் ஒரு ப்ராக்ஸியை உருவாக்குவோம்.
// அசல் ஆப்ஜெக்ட்
const target = {
message: "Hello, World!"
};
// ஒரு காலி ஹேண்ட்லர். அனைத்து செயல்பாடுகளும் டார்கெட்டிற்கு அனுப்பப்படும்.
const handler = {};
// ப்ராக்ஸி ஆப்ஜெக்ட்
const proxy = new Proxy(target, handler);
// ப்ராக்ஸியில் ஒரு பண்பை அணுகுதல்
console.log(proxy.message); // வெளியீடு: Hello, World!
// செயல்பாடு டார்கெட்டிற்கு அனுப்பப்பட்டது
console.log(target.message); // வெளியீடு: Hello, World!
// ப்ராக்ஸி மூலம் ஒரு பண்பை மாற்றுதல்
proxy.anotherMessage = "Hello, Proxy!";
console.log(proxy.anotherMessage); // வெளியீடு: Hello, Proxy!
console.log(target.anotherMessage); // வெளியீடு: Hello, Proxy!
இந்த எடுத்துக்காட்டில், ப்ராக்ஸி அசல் ஆப்ஜெக்டைப் போலவே செயல்படுகிறது. ஹேண்ட்லரில் நாம் ட்ராப்ஸ்களை வரையறுக்கத் தொடங்கும் போதுதான் உண்மையான சக்தி வெளிப்படுகிறது.
ஒரு ப்ராக்ஸியின் உடற்கூறியல்: பொதுவான ட்ராப்ஸ்களை ஆராய்தல்
ஹேண்ட்லர் ஆப்ஜெக்ட்டில் 13 வெவ்வேறு ட்ராப்ஸ்கள் வரை இருக்கலாம், ஒவ்வொன்றும் ஜாவாஸ்கிரிப்ட் ஆப்ஜெக்ட்களின் ஒரு அடிப்படை உள் முறையுடன் தொடர்புடையது. மிகவும் பொதுவான மற்றும் பயனுள்ளவற்றை ஆராய்வோம்.
பண்பு அணுகல் ட்ராப்ஸ் (Property Access Traps)
1. `get(target, property, receiver)`
இது விவாதத்திற்குரிய வகையில் மிகவும் பயன்படுத்தப்படும் ட்ராப் ஆகும். ப்ராக்ஸியின் ஒரு பண்பு படிக்கப்படும்போது இது தூண்டப்படுகிறது.
target
: அசல் ஆப்ஜெக்ட்.property
: அணுகப்படும் பண்பின் பெயர்.receiver
: ப்ராக்ஸி தானே, அல்லது அதிலிருந்து மரபுரிமையாகப் பெற்ற ஒரு ஆப்ஜெக்ட்.
எடுத்துக்காட்டு: இல்லாத பண்புகளுக்கான இயல்புநிலை மதிப்புகள்.
const user = {
firstName: 'John',
lastName: 'Doe',
age: 30
};
const userHandler = {
get(target, property) {
// டார்கெட்டில் பண்பு இருந்தால், அதைத் திருப்பவும்.
// இல்லையெனில், ஒரு இயல்புநிலை செய்தியைத் திருப்பவும்.
return property in target ? target[property] : `பண்பு '${property}' இல்லை.`;
}
};
const userProxy = new Proxy(user, userHandler);
console.log(userProxy.firstName); // வெளியீடு: John
console.log(userProxy.age); // வெளியீடு: 30
console.log(userProxy.country); // வெளியீடு: பண்பு 'country' இல்லை.
2. `set(target, property, value, receiver)`
set
ட்ராப், ப்ராக்ஸியின் ஒரு பண்பிற்கு ஒரு மதிப்பு ஒதுக்கப்படும்போது அழைக்கப்படுகிறது. இது சரிபார்ப்பு, பதிவு செய்தல் அல்லது படிக்க-மட்டும் ஆப்ஜெக்ட்களை உருவாக்குவதற்கு ஏற்றது.
value
: பண்பிற்கு ஒதுக்கப்படும் புதிய மதிப்பு.- ட்ராப் ஒரு பூலியன் மதிப்பைத் திருப்ப வேண்டும்: ஒதுக்கீடு வெற்றிகரமாக இருந்தால்
true
, இல்லையெனில்false
(இது strict mode-ல் ஒருTypeError
-ஐ வீசும்).
எடுத்துக்காட்டு: தரவு சரிபார்ப்பு.
const person = {
name: 'Jane Doe',
age: 25
};
const validationHandler = {
set(target, property, value) {
if (property === 'age') {
if (typeof value !== 'number' || !Number.isInteger(value)) {
throw new TypeError('வயது ஒரு முழு எண்ணாக இருக்க வேண்டும்.');
}
if (value <= 0) {
throw new RangeError('வயது ஒரு நேர்மறை எண்ணாக இருக்க வேண்டும்.');
}
}
// சரிபார்ப்பு வெற்றிகரமாக முடிந்தால், டார்கெட் ஆப்ஜெக்ட்டில் மதிப்பை அமைக்கவும்.
target[property] = value;
// வெற்றியைக் குறிக்கவும்.
return true;
}
};
const personProxy = new Proxy(person, validationHandler);
personProxy.age = 30; // இது செல்லுபடியாகும்
console.log(personProxy.age); // வெளியீடு: 30
try {
personProxy.age = 'thirty'; // TypeError ஐ வீசும்
} catch (e) {
console.error(e.message); // வெளியீடு: வயது ஒரு முழு எண்ணாக இருக்க வேண்டும்.
}
try {
personProxy.age = -5; // RangeError ஐ வீசும்
} catch (e) {
console.error(e.message); // வெளியீடு: வயது ஒரு நேர்மறை எண்ணாக இருக்க வேண்டும்.
}
3. `has(target, property)`
இந்த ட்ராப் in
ஆபரேட்டரை இடைமறிக்கிறது. ஒரு ஆப்ஜெக்ட்டில் எந்த பண்புகள் இருப்பதாகத் தோன்ற வேண்டும் என்பதை நீங்கள் கட்டுப்படுத்த இது அனுமதிக்கிறது.
எடுத்துக்காட்டு: 'தனியார்' பண்புகளை மறைத்தல்.
ஜாவாஸ்கிரிப்ட்டில், தனியார் பண்புகளை ஒரு அடிக்கோடிட்டு (_) தொடங்குவது ஒரு பொதுவான மரபாகும். இந்த பண்புகளை in
ஆபரேட்டரிடமிருந்து மறைக்க has
ட்ராப்பைப் பயன்படுத்தலாம்.
const secretData = {
_apiKey: 'xyz123abc',
publicKey: 'pub456def',
id: 1
};
const hidingHandler = {
has(target, property) {
if (property.startsWith('_')) {
return false; // அது இல்லை என்று பாசாங்கு செய்யவும்
}
return property in target;
}
};
const dataProxy = new Proxy(secretData, hidingHandler);
console.log('publicKey' in dataProxy); // வெளியீடு: true
console.log('_apiKey' in dataProxy); // வெளியீடு: false (அது டார்கெட்டில் இருந்தாலும் கூட)
console.log('id' in dataProxy); // வெளியீடு: true
குறிப்பு: இது in
ஆபரேட்டரை மட்டுமே பாதிக்கிறது. நீங்கள் அதற்கேற்ற get
ட்ராப்பை செயல்படுத்தாத வரை dataProxy._apiKey
போன்ற நேரடி அணுகல் வேலை செய்யும்.
4. `deleteProperty(target, property)`
delete
ஆபரேட்டரைப் பயன்படுத்தி ஒரு பண்பு நீக்கப்படும்போது இந்த ட்ராப் செயல்படுத்தப்படுகிறது. முக்கியமான பண்புகள் நீக்கப்படுவதைத் தடுக்க இது பயனுள்ளதாக இருக்கும்.
இந்த ட்ராப் வெற்றிகரமான நீக்கத்திற்கு true
அல்லது தோல்வியுற்ற நீக்கத்திற்கு false
ஐத் திருப்ப வேண்டும்.
எடுத்துக்காட்டு: பண்புகள் நீக்கப்படுவதைத் தடுத்தல்.
const immutableConfig = {
databaseUrl: 'prod.db.server',
port: 8080
};
const deletionGuardHandler = {
deleteProperty(target, property) {
if (property in target) {
console.warn(`பாதுகாக்கப்பட்ட பண்பை நீக்க முயற்சி: '${property}'. செயல்பாடு மறுக்கப்பட்டது.`);
return false;
}
return true; // பண்பு எப்படியும் இல்லை
}
};
const configProxy = new Proxy(immutableConfig, deletionGuardHandler);
delete configProxy.port;
// கன்சோல் வெளியீடு: பாதுகாக்கப்பட்ட பண்பை நீக்க முயற்சி: 'port'. செயல்பாடு மறுக்கப்பட்டது.
console.log(configProxy.port); // வெளியீடு: 8080 (அது நீக்கப்படவில்லை)
ஆப்ஜெக்ட் கணக்கீடு மற்றும் விளக்க ட்ராப்ஸ்
5. `ownKeys(target)`
Object.keys()
, Object.getOwnPropertyNames()
, Object.getOwnPropertySymbols()
, மற்றும் Reflect.ownKeys()
போன்ற ஒரு ஆப்ஜெக்ட்டின் சொந்த பண்புகளின் பட்டியலைப் பெறும் செயல்பாடுகளால் இந்த ட்ராப் தூண்டப்படுகிறது.
எடுத்துக்காட்டு: கீஸ்களை வடிகட்டுதல்.
முந்தைய 'தனியார்' பண்பு எடுத்துக்காட்டுடன் இதை இணைத்து அவற்றை முழுமையாக மறைப்போம்.
const secretData = {
_apiKey: 'xyz123abc',
publicKey: 'pub456def',
id: 1
};
const keyHidingHandler = {
has(target, property) {
return !property.startsWith('_') && property in target;
},
ownKeys(target) {
return Reflect.ownKeys(target).filter(key => !key.startsWith('_'));
},
get(target, property, receiver) {
// நேரடி அணுகலையும் தடுக்கவும்
if (property.startsWith('_')) {
return undefined;
}
return Reflect.get(target, property, receiver);
}
};
const fullProxy = new Proxy(secretData, keyHidingHandler);
console.log(Object.keys(fullProxy)); // வெளியீடு: ['publicKey', 'id']
console.log('publicKey' in fullProxy); // வெளியீடு: true
console.log('_apiKey' in fullProxy); // வெளியீடு: false
console.log(fullProxy._apiKey); // வெளியீடு: undefined
இங்கே நாம் `Reflect`-ஐப் பயன்படுத்துவதைக் கவனியுங்கள். `Reflect` ஆப்ஜெக்ட், இடைமறிக்கக்கூடிய ஜாவாஸ்கிரிப்ட் செயல்பாடுகளுக்கான முறைகளை வழங்குகிறது, மேலும் அதன் முறைகள் ப்ராக்ஸி ட்ராப்ஸ்களின் அதே பெயர்களையும் கையொப்பங்களையும் கொண்டுள்ளன. அசல் செயல்பாட்டை டார்கெட்டிற்கு அனுப்புவதற்கு `Reflect`-ஐப் பயன்படுத்துவது ஒரு சிறந்த நடைமுறையாகும், இது இயல்புநிலை நடத்தை சரியாகப் பராமரிக்கப்படுவதை உறுதி செய்கிறது.
செயல்பாடு மற்றும் கன்ஸ்ட்ரக்டர் ட்ராப்ஸ்
ப்ராக்ஸிகள் எளிய ஆப்ஜெக்ட்களுக்கு மட்டும் அல்ல. டார்கெட் ஒரு செயல்பாடாக இருக்கும்போது, நீங்கள் அழைப்புகளையும் கன்ஸ்ட்ரக்ஷன்களையும் இடைமறிக்கலாம்.
6. `apply(target, thisArg, argumentsList)`
ஒரு செயல்பாட்டின் ப்ராக்ஸி செயல்படுத்தப்படும்போது இந்த ட்ராப் அழைக்கப்படுகிறது. இது செயல்பாட்டு அழைப்பை இடைமறிக்கிறது.
target
: அசல் செயல்பாடு.thisArg
: அழைப்பிற்கானthis
சூழல்.argumentsList
: செயல்பாட்டிற்கு அனுப்பப்பட்ட ஆர்க்யுமெண்ட்களின் பட்டியல்.
எடுத்துக்காட்டு: செயல்பாட்டு அழைப்புகள் மற்றும் அவற்றின் ஆர்க்யுமெண்ட்களை பதிவு செய்தல்.
function sum(a, b) {
return a + b;
}
const loggingHandler = {
apply(target, thisArg, argumentsList) {
console.log(`'${target.name}' செயல்பாட்டை ஆர்க்யுமெண்ட்களுடன் அழைக்கப்படுகிறது: ${argumentsList}`);
// சரியான சூழல் மற்றும் ஆர்க்யுமெண்ட்களுடன் அசல் செயல்பாட்டை இயக்கவும்
const result = Reflect.apply(target, thisArg, argumentsList);
console.log(`'${target.name}' செயல்பாடு திரும்பியது: ${result}`);
return result;
}
};
const proxiedSum = new Proxy(sum, loggingHandler);
proxiedSum(5, 10);
// கன்சோல் வெளியீடு:
// 'sum' செயல்பாட்டை ஆர்க்யுமெண்ட்களுடன் அழைக்கப்படுகிறது: 5,10
// 'sum' செயல்பாடு திரும்பியது: 15
7. `construct(target, argumentsList, newTarget)`
இந்த ட்ராப் ஒரு கிளாஸ் அல்லது செயல்பாட்டின் ப்ராக்ஸியில் new
ஆபரேட்டரின் பயன்பாட்டை இடைமறிக்கிறது.
எடுத்துக்காட்டு: சிங்கிள்டன் பேட்டர்ன் செயல்படுத்தல்.
class MyDatabaseConnection {
constructor(url) {
this.url = url;
console.log(`${this.url} உடன் இணைக்கப்படுகிறது...`);
}
}
let instance;
const singletonHandler = {
construct(target, argumentsList) {
if (!instance) {
console.log('புதிய நிகழ்வை உருவாக்குகிறது.');
instance = Reflect.construct(target, argumentsList);
}
console.log('இருக்கும் நிகழ்வைத் திருப்புகிறது.');
return instance;
}
};
const ProxiedConnection = new Proxy(MyDatabaseConnection, singletonHandler);
const conn1 = new ProxiedConnection('db://primary');
// கன்சோல் வெளியீடு:
// புதிய நிகழ்வை உருவாக்குகிறது.
// db://primary உடன் இணைக்கப்படுகிறது...
// இருக்கும் நிகழ்வைத் திருப்புகிறது.
const conn2 = new ProxiedConnection('db://secondary'); // URL புறக்கணிக்கப்படும்
// கன்சோல் வெளியீடு:
// இருக்கும் நிகழ்வைத் திருப்புகிறது.
console.log(conn1 === conn2); // வெளியீடு: true
console.log(conn1.url); // வெளியீடு: db://primary
console.log(conn2.url); // வெளியீடு: db://primary
நடைமுறை பயன்பாட்டு வழக்குகள் மற்றும் மேம்பட்ட பேட்டர்ன்கள்
தனிப்பட்ட ட்ராப்ஸ்களைப் பற்றிப் பார்த்தோம், இப்போது அவை நிஜ உலகப் பிரச்சனைகளைத் தீர்க்க எப்படி இணைக்கப்படலாம் என்று பார்ப்போம்.
1. ஏபிஐ சுருக்கம் மற்றும் தரவு மாற்றம் (API Abstraction and Data Transformation)
ஏபிஐ-கள் பெரும்பாலும் உங்கள் பயன்பாட்டின் மரபுகளுடன் பொருந்தாத வடிவத்தில் தரவைத் தருகின்றன (எ.கா., snake_case
vs. camelCase
). ஒரு ப்ராக்ஸி இந்த மாற்றத்தை வெளிப்படையாக கையாள முடியும்.
function snakeToCamel(s) {
return s.replace(/(_\w)/g, (m) => m[1].toUpperCase());
}
// இது ஒரு ஏபிஐ-யிலிருந்து வரும் நமது மூல தரவு என்று கற்பனை செய்து கொள்ளுங்கள்
const apiResponse = {
user_id: 123,
first_name: 'Alice',
last_name: 'Wonderland',
account_status: 'active'
};
const camelCaseHandler = {
get(target, property) {
const camelCaseProperty = snakeToCamel(property);
// camelCase பதிப்பு நேரடியாக இருக்கிறதா என்று சரிபார்க்கவும்
if (camelCaseProperty in target) {
return target[camelCaseProperty];
}
// அசல் பண்பு பெயருக்குத் திரும்பு
if (property in target) {
return target[property];
}
return undefined;
}
};
const userModel = new Proxy(apiResponse, camelCaseHandler);
// snake_case இல் சேமிக்கப்பட்டிருந்தாலும், இப்போது நாம் camelCase ஐப் பயன்படுத்தி பண்புகளை அணுகலாம்
console.log(userModel.userId); // வெளியீடு: 123
console.log(userModel.firstName); // வெளியீடு: Alice
console.log(userModel.accountStatus); // வெளியீடு: active
2. அப்சர்வேபிள்கள் மற்றும் தரவு பிணைப்பு (நவீன கட்டமைப்புகளின் மையம்)
ப்ராக்ஸிகள் Vue 3 போன்ற நவீன கட்டமைப்புகளில் உள்ள வினைத்திறன் அமைப்புகளுக்குப் பின்னால் உள்ள இயந்திரம். நீங்கள் ஒரு ப்ராக்ஸி செய்யப்பட்ட நிலை ஆப்ஜெக்ட்டில் ஒரு பண்பை மாற்றும்போது, set
ட்ராப் பயனர் இடைமுகம் அல்லது பயன்பாட்டின் பிற பகுதிகளில் புதுப்பிப்புகளைத் தூண்டுவதற்குப் பயன்படுத்தப்படலாம்.
இங்கே ஒரு மிகவும் எளிமைப்படுத்தப்பட்ட எடுத்துக்காட்டு:
function createObservable(target, callback) {
const handler = {
set(obj, prop, value) {
const result = Reflect.set(obj, prop, value);
callback(prop, value); // மாற்றத்தின் போது கால்பேக்கை தூண்டவும்
return result;
}
};
return new Proxy(target, handler);
}
const state = {
count: 0,
message: 'Hello'
};
function render(prop, value) {
console.log(`மாற்றம் கண்டறியப்பட்டது: '${prop}' என்ற பண்பு '${value}' என அமைக்கப்பட்டது. பயனர் இடைமுகத்தை மீண்டும் ரெண்டரிங் செய்கிறது...`);
}
const observableState = createObservable(state, render);
observableState.count = 1;
// கன்சோல் வெளியீடு: மாற்றம் கண்டறியப்பட்டது: 'count' என்ற பண்பு '1' என அமைக்கப்பட்டது. பயனர் இடைமுகத்தை மீண்டும் ரெண்டரிங் செய்கிறது...
observableState.message = 'Goodbye';
// கன்சோல் வெளியீடு: மாற்றம் கண்டறியப்பட்டது: 'message' என்ற பண்பு 'Goodbye' என அமைக்கப்பட்டது. பயனர் இடைமுகத்தை மீண்டும் ரெண்டரிங் செய்கிறது...
3. எதிர்மறை அரே குறியீடுகள் (Negative Array Indices)
பைதான் போன்ற மொழிகளைப் போலவே, -1
கடைசி உறுப்பைக் குறிக்கும் எதிர்மறை குறியீடுகளை ஆதரிக்க நேட்டிவ் அரே நடத்தையை விரிவுபடுத்துவது ஒரு உன்னதமான மற்றும் வேடிக்கையான எடுத்துக்காட்டாகும்.
function createNegativeArrayProxy(arr) {
const handler = {
get(target, property) {
const index = Number(property);
if (!Number.isNaN(index) && index < 0) {
// எதிர்மறை குறியீட்டை இறுதியிலிருந்து ஒரு நேர்மறை குறியீடாக மாற்றவும்
property = String(target.length + index);
}
return Reflect.get(target, property);
}
};
return new Proxy(arr, handler);
}
const originalArray = ['a', 'b', 'c', 'd', 'e'];
const proxiedArray = createNegativeArrayProxy(originalArray);
console.log(proxiedArray[0]); // வெளியீடு: a
console.log(proxiedArray[-1]); // வெளியீடு: e
console.log(proxiedArray[-2]); // வெளியீடு: d
console.log(proxiedArray.length); // வெளியீடு: 5
செயல்திறன் பரிசீலனைகள் மற்றும் சிறந்த நடைமுறைகள்
ப்ராக்ஸிகள் நம்பமுடியாத அளவிற்கு சக்திவாய்ந்தவை என்றாலும், அவை ஒரு மந்திரக்கோல் அல்ல. அவற்றின் தாக்கங்களைப் புரிந்துகொள்வது முக்கியம்.
செயல்திறன் கூடுதல் சுமை
ஒரு ப்ராக்ஸி ஒரு மறைமுக அடுக்கை அறிமுகப்படுத்துகிறது. ஒரு ப்ராக்ஸி செய்யப்பட்ட ஆப்ஜெக்ட்டில் உள்ள ஒவ்வொரு செயல்பாடும் ஹேண்ட்லர் வழியாகச் செல்ல வேண்டும், இது ஒரு எளிய ஆப்ஜெக்ட்டில் நேரடி செயல்பாட்டுடன் ஒப்பிடும்போது ஒரு சிறிய அளவு கூடுதல் சுமையைச் சேர்க்கிறது. பெரும்பாலான பயன்பாடுகளுக்கு (தரவு சரிபார்ப்பு அல்லது கட்டமைப்பு-நிலை வினைத்திறன் போன்றவை), இந்த கூடுதல் சுமை மிகக் குறைவு. இருப்பினும், செயல்திறன்-முக்கியமான குறியீட்டில், அதாவது மில்லியன் கணக்கான உருப்படிகளைச் செயலாக்கும் ஒரு இறுக்கமான லூப்பில், இது ஒரு இடையூறாக மாறும். செயல்திறன் ஒரு முதன்மைக் கவலையாக இருந்தால் எப்போதும் பெஞ்ச்மார்க் செய்யவும்.
ப்ராக்ஸி மாறிலிகள் (Proxy Invariants)
ஒரு ட்ராப் டார்கெட் ஆப்ஜெக்ட்டின் தன்மையைப் பற்றி முழுமையாகப் பொய் சொல்ல முடியாது. ஜாவாஸ்கிரிப்ட் 'மாறிலிகள்' எனப்படும் ஒரு தொகுதி விதிகளைச் செயல்படுத்துகிறது, ப்ராக்ஸி ட்ராப்ஸ் அவற்றுக்குக் கீழ்ப்படிய வேண்டும். ஒரு மாறிலியை மீறுவது ஒரு TypeError
-ஐ ஏற்படுத்தும்.
எடுத்துக்காட்டாக, deleteProperty
ட்ராப்பிற்கான ஒரு மாறிலி என்னவென்றால், டார்கெட் ஆப்ஜெக்ட்டில் தொடர்புடைய பண்பு மாற்றியமைக்க முடியாததாக (non-configurable) இருந்தால் அது true
(வெற்றியைக் குறிக்கிறது) எனத் திருப்ப முடியாது. இது நீக்க முடியாத ஒரு பண்பை நீக்கிவிட்டதாக ப்ராக்ஸி கூறுவதைத் தடுக்கிறது.
const target = {};
Object.defineProperty(target, 'unbreakable', { value: 10, configurable: false });
const handler = {
deleteProperty(target, prop) {
// இது மாறிலியை மீறும்
return true;
}
};
const proxy = new Proxy(target, handler);
try {
delete proxy.unbreakable; // இது ஒரு பிழையை வீசும்
} catch (e) {
console.error(e.message);
// வெளியீடு: 'deleteProperty' on proxy: returned true for non-configurable property 'unbreakable'
}
ப்ராக்ஸிகளை எப்போது பயன்படுத்துவது (மற்றும் எப்போது பயன்படுத்தக்கூடாது)
- பயன்படுத்த ஏற்றது: கட்டமைப்புகள் மற்றும் நூலகங்களை உருவாக்குதல் (எ.கா., நிலை மேலாண்மை, ORMs), பிழைத்திருத்தம் மற்றும் பதிவு செய்தல், வலுவான சரிபார்ப்பு அமைப்புகளைச் செயல்படுத்துதல், மற்றும் அடிப்படை தரவுக் கட்டமைப்புகளைச் சுருக்கும் சக்திவாய்ந்த ஏபிஐ-களை உருவாக்குதல்.
- மாற்றுகளைக் கருத்தில் கொள்க: செயல்திறன்-முக்கியமான அல்காரிதம்கள், ஒரு கிளாஸ் அல்லது ஒரு பேக்டரி செயல்பாடு போதுமானதாக இருக்கும் எளிய ஆப்ஜெக்ட் நீட்டிப்புகள், அல்லது ES6 ஆதரவு இல்லாத மிக பழைய உலாவிகளை ஆதரிக்க வேண்டியிருக்கும் போது.
திரும்பப்பெறக்கூடிய ப்ராக்ஸிகள் (Revocable Proxies)
ஒரு ப்ராக்ஸியை 'முடக்க' வேண்டிய சூழ்நிலைகளுக்கு (எ.கா., பாதுகாப்பு காரணங்களுக்காக அல்லது நினைவக மேலாண்மைக்காக), ஜாவாஸ்கிரிப்ட் Proxy.revocable()
-ஐ வழங்குகிறது. இது ப்ராக்ஸி மற்றும் ஒரு revoke
செயல்பாடு இரண்டையும் கொண்ட ஒரு ஆப்ஜெக்ட்டைத் திருப்புகிறது.
const target = { data: 'sensitive' };
const handler = {};
const { proxy, revoke } = Proxy.revocable(target, handler);
console.log(proxy.data); // வெளியீடு: sensitive
// இப்போது, நாம் ப்ராக்ஸியின் அணுகலைத் திரும்பப் பெறுகிறோம்
revoke();
try {
console.log(proxy.data); // இது ஒரு பிழையை வீசும்
} catch (e) {
console.error(e.message);
// வெளியீடு: Cannot perform 'get' on a proxy that has been revoked
}
ப்ராக்ஸிகள் மற்றும் பிற மெட்டாபுரோகிராமிங் நுட்பங்கள்
ப்ராக்ஸிகளுக்கு முன்பு, டெவலப்பர்கள் இதே போன்ற இலக்குகளை அடைய மற்ற முறைகளைப் பயன்படுத்தினர். ப்ராக்ஸிகள் எப்படி ஒப்பிடப்படுகின்றன என்பதைப் புரிந்துகொள்வது பயனுள்ளதாக இருக்கும்.
`Object.defineProperty()`
Object.defineProperty()
ஒரு ஆப்ஜெக்ட்டை நேரடியாக மாற்றியமைக்கிறது, குறிப்பிட்ட பண்புகளுக்கு கெட்டர்கள் மற்றும் செட்டர்களை வரையறுப்பதன் மூலம். ப்ராக்ஸிகள், மறுபுறம், அசல் ஆப்ஜெக்ட்டை 전혀 மாற்றாது; அவை அதை உறையிடுகின்றன.
- வரம்பு: `defineProperty` ஒரு பண்பு அடிப்படையில் செயல்படுகிறது. நீங்கள் கண்காணிக்க விரும்பும் ஒவ்வொரு பண்புக்கும் ஒரு கெட்டர்/செட்டரை வரையறுக்க வேண்டும். ஒரு ப்ராக்ஸியின்
get
மற்றும்set
ட்ராப்ஸ் உலகளாவியவை, பின்னர் சேர்க்கப்படும் புதியவை உட்பட எந்தவொரு பண்பின் மீதான செயல்பாடுகளையும் பிடிக்கின்றன. - திறன்கள்: ப்ராக்ஸிகள்
deleteProperty
,in
ஆபரேட்டர், மற்றும் செயல்பாட்டு அழைப்புகள் போன்ற பரந்த அளவிலான செயல்பாடுகளை இடைமறிக்க முடியும், `defineProperty` இதைச் செய்ய முடியாது.
முடிவுரை: மெய்நிகராக்கத்தின் சக்தி
ஜாவாஸ்கிரிப்ட் ப்ராக்ஸி ஏபிஐ ஒரு புத்திசாலித்தனமான அம்சத்தை விட மேலானது; இது நாம் ஆப்ஜெக்ட்களை வடிவமைத்து அவற்றுடன் தொடர்பு கொள்ளும் விதத்தில் ஒரு அடிப்படை மாற்றமாகும். அடிப்படை செயல்பாடுகளை இடைமறித்து தனிப்பயனாக்க நம்மை அனுமதிப்பதன் மூலம், ப்ராக்ஸிகள் சக்திவாய்ந்த பேட்டர்ன்களின் உலகிற்கு கதவைத் திறக்கின்றன: தடையற்ற தரவு சரிபார்ப்பு மற்றும் மாற்றத்திலிருந்து நவீன பயனர் இடைமுகங்களை இயக்கும் வினைத்திறன் அமைப்புகள் வரை.
அவை ஒரு சிறிய செயல்திறன் செலவு மற்றும் பின்பற்ற வேண்டிய ஒரு தொகுதி விதிகளுடன் வந்தாலும், சுத்தமான, பிரிக்கப்பட்ட, மற்றும் சக்திவாய்ந்த சுருக்கங்களை உருவாக்கும் அவற்றின் திறன் ஈடு இணையற்றது. ஆப்ஜெக்ட்களை மெய்நிகராக்குவதன் மூலம், நீங்கள் மிகவும் வலுவான, பராமரிக்கக்கூடிய, மற்றும் வெளிப்படையான அமைப்புகளை உருவாக்க முடியும். அடுத்த முறை நீங்கள் தரவு மேலாண்மை, சரிபார்ப்பு, அல்லது கவனிக்கக்கூடிய தன்மை சம்பந்தப்பட்ட ஒரு சிக்கலான சவாலை எதிர்கொள்ளும்போது, ஒரு ப்ராக்ஸி சரியான கருவியாக இருக்குமா என்று கருத்தில் கொள்ளுங்கள். அது உங்கள் கருவித்தொகுப்பில் உள்ள மிக நேர்த்தியான தீர்வாக இருக்கலாம்.