ગુજરાતી

જાવાસ્ક્રિપ્ટ પ્રોક્સી API માં નિપુણતા મેળવવા માટે વૈશ્વિક ડેવલપર્સ માટે એક વિસ્તૃત માર્ગદર્શિકા. પ્રેક્ટિકલ ઉદાહરણો, ઉપયોગના કેસો અને પર્ફોર્મન્સ ટિપ્સ સાથે ઓબ્જેક્ટ ઓપરેશન્સને ઇન્ટરસેપ્ટ અને કસ્ટમાઇઝ કરવાનું શીખો.

જાવાસ્ક્રિપ્ટ પ્રોક્સી API: ઓબ્જેક્ટ બિહેવિયર મોડિફિકેશનમાં ઊંડાણપૂર્વકનો અભ્યાસ

આધુનિક જાવાસ્ક્રિપ્ટના વિકસતા લેન્ડસ્કેપમાં, ડેવલપર્સ ડેટાને મેનેજ કરવા અને તેની સાથે ક્રિયાપ્રતિક્રિયા કરવા માટે વધુ શક્તિશાળી અને ઉત્કૃષ્ટ રીતો શોધી રહ્યા છે. જ્યારે ક્લાસ, મોડ્યુલ્સ અને async/await જેવી સુવિધાઓએ કોડ લખવાની રીતમાં ક્રાંતિ લાવી છે, ત્યારે ECMAScript 2015 (ES6) માં રજૂ કરાયેલ એક શક્તિશાળી મેટાપ્રોગ્રામિંગ સુવિધા છે જેનો ઘણીવાર ઓછો ઉપયોગ થાય છે: તે છે પ્રોક્સી API.

મેટાપ્રોગ્રામિંગ શબ્દ ભયાવહ લાગી શકે છે, પરંતુ તે ફક્ત અન્ય કોડ પર કાર્ય કરે તેવો કોડ લખવાનો ખ્યાલ છે. પ્રોક્સી API આ માટે જાવાસ્ક્રિપ્ટનું મુખ્ય સાધન છે, જે તમને અન્ય ઓબ્જેક્ટ માટે 'પ્રોક્સી' બનાવવાની મંજૂરી આપે છે, જે તે ઓબ્જેક્ટ માટેના મૂળભૂત ઓપરેશન્સને ઇન્ટરસેપ્ટ કરી શકે છે અને ફરીથી વ્યાખ્યાયિત કરી શકે છે. તે એક ઓબ્જેક્ટની સામે કસ્ટમાઇઝ કરી શકાય તેવો ગેટકીપર મૂકવા જેવું છે, જે તમને તેના એક્સેસ અને ફેરફાર પર સંપૂર્ણ નિયંત્રણ આપે છે.

આ વિસ્તૃત માર્ગદર્શિકા પ્રોક્સી API ને સરળ બનાવશે. અમે તેના મૂળભૂત ખ્યાલોનું અન્વેષણ કરીશું, તેની વિવિધ ક્ષમતાઓને વ્યવહારુ ઉદાહરણો સાથે સમજીશું, અને અદ્યતન ઉપયોગના કેસો અને પર્ફોર્મન્સ સંબંધિત વિચારણાઓની ચર્ચા કરીશું. અંત સુધીમાં, તમે સમજી શકશો કે શા માટે પ્રોક્સીઝ આધુનિક ફ્રેમવર્કનો પાયાનો પથ્થર છે અને તમે ક્લીન, વધુ શક્તિશાળી અને વધુ જાળવી શકાય તેવો કોડ લખવા માટે તેનો કેવી રીતે લાભ લઈ શકો છો.

મૂળભૂત ખ્યાલોને સમજવું: ટાર્ગેટ, હેન્ડલર અને ટ્રેપ્સ

પ્રોક્સી API ત્રણ મૂળભૂત ઘટકો પર બનેલ છે. તેમની ભૂમિકાઓને સમજવી એ પ્રોક્સીમાં નિપુણતા મેળવવાની ચાવી છે.

પ્રોક્સી બનાવવાનો સિન્ટેક્સ સીધોસાદો છે:

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 જેટલા વિવિધ ટ્રેપ્સ હોઈ શકે છે, જે દરેક જાવાસ્ક્રિપ્ટ ઓબ્જેક્ટ્સની મૂળભૂત આંતરિક મેથડને અનુરૂપ છે. ચાલો સૌથી સામાન્ય અને ઉપયોગી ટ્રેપ્સનું અન્વેષણ કરીએ.

પ્રોપર્ટી એક્સેસ ટ્રેપ્સ

1. `get(target, property, receiver)`

આ દલીલપૂર્વક સૌથી વધુ વપરાતો ટ્રેપ છે. જ્યારે પ્રોક્સીની કોઈ પ્રોપર્ટી વાંચવામાં આવે ત્યારે તે ટ્રિગર થાય છે.

ઉદાહરણ: અસ્તિત્વમાં ન હોય તેવી પ્રોપર્ટીઝ માટે ડિફોલ્ટ વેલ્યુ.


const user = {
  firstName: 'John',
  lastName: 'Doe',
  age: 30
};

const userHandler = {
  get(target, property) {
    // જો પ્રોપર્ટી ટાર્ગેટ પર અસ્તિત્વમાં હોય, તો તેને પરત કરો.
    // અન્યથા, ડિફોલ્ટ સંદેશ પરત કરો.
    return property in target ? target[property] : `Property '${property}' does not exist.`;
  }
};

const userProxy = new Proxy(user, userHandler);

console.log(userProxy.firstName); // આઉટપુટ: John
console.log(userProxy.age);       // આઉટપુટ: 30
console.log(userProxy.country);   // આઉટપુટ: Property 'country' does not exist.

2. `set(target, property, value, receiver)`

જ્યારે પ્રોક્સીની કોઈ પ્રોપર્ટીને વેલ્યુ અસાઇન કરવામાં આવે ત્યારે set ટ્રેપ કૉલ કરવામાં આવે છે. તે વેલિડેશન, લોગિંગ અથવા રીડ-ઓન્લી ઓબ્જેક્ટ બનાવવા માટે યોગ્ય છે.

ઉદાહરણ: ડેટા વેલિડેશન.


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('Age must be an integer.');
      }
      if (value <= 0) {
        throw new RangeError('Age must be a positive number.');
      }
    }

    // જો વેલિડેશન પાસ થાય, તો ટાર્ગેટ ઓબ્જેક્ટ પર વેલ્યુ સેટ કરો.
    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); // આઉટપુટ: Age must be an integer.
}

try {
  personProxy.age = -5; // RangeError ફેંકશે
} catch (e) {
  console.error(e.message); // આઉટપુટ: Age must be a positive number.
}

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 ઓપરેટરને અસર કરે છે. dataProxy._apiKey જેવો સીધો એક્સેસ હજુ પણ કામ કરશે સિવાય કે તમે સંબંધિત get ટ્રેપ પણ લાગુ કરો.

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(`Attempted to delete protected property: '${property}'. Operation denied.`);
      return false;
    }
    return true; // પ્રોપર્ટી ગમે તેમ પણ અસ્તિત્વમાં નહોતી
  }
};

const configProxy = new Proxy(immutableConfig, deletionGuardHandler);

delete configProxy.port;
// કન્સોલ આઉટપુટ: Attempted to delete protected property: 'port'. Operation denied.

console.log(configProxy.port); // આઉટપુટ: 8080 (તે ડિલીટ થઈ ન હતી)

ઓબ્જેક્ટ એન્યુમરેશન અને ડિસ્ક્રિપ્શન ટ્રેપ્સ

5. `ownKeys(target)`

આ ટ્રેપ એવા ઓપરેશન્સ દ્વારા ટ્રિગર થાય છે જે ઓબ્જેક્ટની પોતાની પ્રોપર્ટીઝની સૂચિ મેળવે છે, જેમ કે Object.keys(), Object.getOwnPropertyNames(), Object.getOwnPropertySymbols(), અને Reflect.ownKeys().

ઉદાહરણ: કીઝ (Keys) ફિલ્ટર કરવી.

ચાલો આને આપણા અગાઉના 'પ્રાઇવેટ' પ્રોપર્ટી ઉદાહરણ સાથે જોડીએ જેથી તેમને સંપૂર્ણપણે છુપાવી શકાય.


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)`

જ્યારે કોઈ ફંક્શનની પ્રોક્સી એક્ઝિક્યુટ થાય ત્યારે આ ટ્રેપ કૉલ કરવામાં આવે છે. તે ફંક્શન કૉલને ઇન્ટરસેપ્ટ કરે છે.

ઉદાહરણ: ફંક્શન કૉલ્સ અને તેમના આર્ગ્યુમેન્ટ્સને લોગ કરવું.


function sum(a, b) {
  return a + b;
}

const loggingHandler = {
  apply(target, thisArg, argumentsList) {
    console.log(`Calling function '${target.name}' with arguments: ${argumentsList}`);
    // મૂળ ફંક્શનને સાચા કોન્ટેક્સ્ટ અને આર્ગ્યુમેન્ટ્સ સાથે એક્ઝિક્યુટ કરો
    const result = Reflect.apply(target, thisArg, argumentsList);
    console.log(`Function '${target.name}' returned: ${result}`);
    return result;
  }
};

const proxiedSum = new Proxy(sum, loggingHandler);

proxiedSum(5, 10);
// કન્સોલ આઉટપુટ:
// Calling function 'sum' with arguments: 5,10
// Function 'sum' returned: 15

7. `construct(target, argumentsList, newTarget)`

આ ટ્રેપ ક્લાસ અથવા ફંક્શનની પ્રોક્સી પર new ઓપરેટરના ઉપયોગને ઇન્ટરસેપ્ટ કરે છે.

ઉદાહરણ: સિંગલટન પેટર્નનો અમલ.


class MyDatabaseConnection {
  constructor(url) {
    this.url = url;
    console.log(`Connecting to ${this.url}...`);
  }
}

let instance;

const singletonHandler = {
  construct(target, argumentsList) {
    if (!instance) {
      console.log('Creating new instance.');
      instance = Reflect.construct(target, argumentsList);
    }
    console.log('Returning existing instance.');
    return instance;
  }
};

const ProxiedConnection = new Proxy(MyDatabaseConnection, singletonHandler);

const conn1 = new ProxiedConnection('db://primary');
// કન્સોલ આઉટપુટ:
// Creating new instance.
// Connecting to db://primary...
// Returning existing instance.

const conn2 = new ProxiedConnection('db://secondary'); // URL અવગણવામાં આવશે
// કન્સોલ આઉટપુટ:
// Returning existing instance.

console.log(conn1 === conn2); // આઉટપુટ: true
console.log(conn1.url); // આઉટપુટ: db://primary
console.log(conn2.url); // આઉટપુટ: db://primary

વ્યવહારુ ઉપયોગના કેસો અને અદ્યતન પેટર્ન્સ

હવે જ્યારે આપણે વ્યક્તિગત ટ્રેપ્સને આવરી લીધા છે, ચાલો જોઈએ કે વાસ્તવિક દુનિયાની સમસ્યાઓ ઉકેલવા માટે તેમને કેવી રીતે જોડી શકાય છે.

1. API એબ્સ્ટ્રેક્શન અને ડેટા ટ્રાન્સફોર્મેશન

APIs ઘણીવાર એવા ફોર્મેટમાં ડેટા પરત કરે છે જે તમારી એપ્લિકેશનના નિયમો સાથે મેળ ખાતો નથી (દા.ત., snake_case વિ. camelCase). પ્રોક્સી આ રૂપાંતરણને પારદર્શક રીતે હેન્ડલ કરી શકે છે.


function snakeToCamel(s) {
  return s.replace(/(_\w)/g, (m) => m[1].toUpperCase());
}

// કલ્પના કરો કે આ API માંથી અમારો રો ડેટા છે
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);

// હવે આપણે camelCase નો ઉપયોગ કરીને પ્રોપર્ટીઝ એક્સેસ કરી શકીએ છીએ, ભલે તે snake_case તરીકે સંગ્રહિત હોય
console.log(userModel.userId);        // આઉટપુટ: 123
console.log(userModel.firstName);     // આઉટપુટ: Alice
console.log(userModel.accountStatus); // આઉટપુટ: active

2. ઓબ્ઝર્વેબલ્સ અને ડેટા બાઈન્ડિંગ (આધુનિક ફ્રેમવર્કનું મૂળ)

Vue 3 જેવા આધુનિક ફ્રેમવર્ક્સમાં રિએક્ટિવિટી સિસ્ટમ્સ પાછળ પ્રોક્સીઝ એ એન્જિન છે. જ્યારે તમે પ્રોક્સી કરેલ સ્ટેટ ઓબ્જેક્ટ પર કોઈ પ્રોપર્ટી બદલો છો, ત્યારે UI અથવા એપ્લિકેશનના અન્ય ભાગોમાં અપડેટ્સ ટ્રિગર કરવા માટે 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(`CHANGE DETECTED: The property '${prop}' was set to '${value}'. Re-rendering UI...`);
}

const observableState = createObservable(state, render);

observableState.count = 1;
// કન્સોલ આઉટપુટ: CHANGE DETECTED: The property 'count' was set to '1'. Re-rendering UI...

observableState.message = 'Goodbye';
// કન્સોલ આઉટપુટ: CHANGE DETECTED: The property 'message' was set to 'Goodbye'. Re-rendering UI...

3. નેગેટિવ એરે ઇન્ડેક્સ

એક ક્લાસિક અને મનોરંજક ઉદાહરણ એ છે કે નેગેટિવ ઇન્ડેક્સને સપોર્ટ કરવા માટે મૂળ એરે વર્તણૂકને વિસ્તારવી, જ્યાં -1 છેલ્લા એલિમેન્ટનો સંદર્ભ આપે છે, જે Python જેવી ભાષાઓ જેવું જ છે.


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

પર્ફોર્મન્સ સંબંધિત વિચારણાઓ અને શ્રેષ્ઠ પદ્ધતિઓ

જ્યારે પ્રોક્સીઝ અતિશય શક્તિશાળી છે, તે કોઈ જાદુઈ ગોળી નથી. તેમની અસરોને સમજવી મહત્વપૂર્ણ છે.

પર્ફોર્મન્સ ઓવરહેડ

પ્રોક્સી એક ઇનડાયરેક્શનનું સ્તર રજૂ કરે છે. પ્રોક્સી કરેલા ઓબ્જેક્ટ પર દરેક ઓપરેશન હેન્ડલરમાંથી પસાર થવું જોઈએ, જે સાદા ઓબ્જેક્ટ પર સીધા ઓપરેશનની તુલનામાં થોડો ઓવરહેડ ઉમેરે છે. મોટાભાગની એપ્લિકેશન્સ (જેમ કે ડેટા વેલિડેશન અથવા ફ્રેમવર્ક-સ્તરની રિએક્ટિવિટી) માટે, આ ઓવરહેડ નહિવત્ છે. જોકે, પર્ફોર્મન્સ-ક્રિટિકલ કોડમાં, જેમ કે લાખો આઇટમ્સની પ્રક્રિયા કરતી ટાઈટ લૂપમાં, આ એક બોટલનેક બની શકે છે. જો પર્ફોર્મન્સ પ્રાથમિક ચિંતા હોય તો હંમેશા બેન્ચમાર્ક કરો.

પ્રોક્સી ઇન્વેરિયન્ટ્સ

એક ટ્રેપ ટાર્ગેટ ઓબ્જેક્ટના સ્વભાવ વિશે સંપૂર્ણપણે ખોટું બોલી શકતો નથી. જાવાસ્ક્રિપ્ટ 'ઇન્વેરિયન્ટ્સ' તરીકે ઓળખાતા નિયમોનો સમૂહ લાગુ કરે છે જેનું પ્રોક્સી ટ્રેપ્સે પાલન કરવું આવશ્યક છે. ઇન્વેરિયન્ટનું ઉલ્લંઘન કરવાથી TypeError પરિણમશે.

ઉદાહરણ તરીકે, deleteProperty ટ્રેપ માટે એક ઇન્વેરિયન્ટ એ છે કે તે 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'
}

પ્રોક્સીનો ઉપયોગ ક્યારે કરવો (અને ક્યારે નહીં)

રિવોકેબલ પ્રોક્સીઝ

એવા સંજોગો માટે જ્યાં તમારે પ્રોક્સીને 'બંધ' કરવાની જરૂર પડી શકે છે (દા.ત., સુરક્ષા કારણોસર અથવા મેમરી મેનેજમેન્ટ માટે), જાવાસ્ક્રિપ્ટ 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() ચોક્કસ પ્રોપર્ટીઝ માટે ગેટર્સ અને સેટર્સ વ્યાખ્યાયિત કરીને સીધા ઓબ્જેક્ટમાં ફેરફાર કરે છે. બીજી બાજુ, પ્રોક્સીઝ મૂળ ઓબ્જેક્ટમાં બિલકુલ ફેરફાર કરતા નથી; તેઓ તેને રેપ કરે છે.

નિષ્કર્ષ: વર્ચ્યુઅલાઈઝેશનની શક્તિ

જાવાસ્ક્રિપ્ટ પ્રોક્સી API એ માત્ર એક ચતુર સુવિધા કરતાં વધુ છે; તે આપણે ઓબ્જેક્ટ્સને કેવી રીતે ડિઝાઇન અને તેની સાથે ક્રિયાપ્રતિક્રિયા કરી શકીએ છીએ તેમાં એક મૂળભૂત પરિવર્તન છે. આપણને મૂળભૂત ઓપરેશન્સને ઇન્ટરસેપ્ટ અને કસ્ટમાઇઝ કરવાની મંજૂરી આપીને, પ્રોક્સીઝ શક્તિશાળી પેટર્ન્સની દુનિયાના દરવાજા ખોલે છે: સીમલેસ ડેટા વેલિડેશન અને ટ્રાન્સફોર્મેશનથી લઈને આધુનિક યુઝર ઇન્ટરફેસને શક્તિ આપતી રિએક્ટિવ સિસ્ટમ્સ સુધી.

જ્યારે તેઓ થોડી પર્ફોર્મન્સ કિંમત અને પાલન કરવાના નિયમોના સમૂહ સાથે આવે છે, ત્યારે ક્લીન, ડીકપલ્ડ અને શક્તિશાળી એબ્સ્ટ્રેક્શન્સ બનાવવાની તેમની ક્ષમતા અજોડ છે. ઓબ્જેક્ટ્સને વર્ચ્યુઅલાઈઝ કરીને, તમે એવી સિસ્ટમ્સ બનાવી શકો છો જે વધુ મજબૂત, જાળવી શકાય તેવી અને અભિવ્યક્ત હોય. આગલી વખતે જ્યારે તમે ડેટા મેનેજમેન્ટ, વેલિડેશન અથવા ઓબ્ઝર્વેબિલિટી સંબંધિત કોઈ જટિલ પડકારનો સામનો કરો, ત્યારે વિચારો કે શું પ્રોક્સી તે કામ માટે યોગ્ય સાધન છે. તે તમારા ટૂલકિટમાં સૌથી ઉત્કૃષ્ટ ઉકેલ હોઈ શકે છે.