v2.5.2
Giriş yap

JavaScript'de Proxy Özelliği: Ne İşe Yarar ve Nasıl Kullanılır?

Günümüzde JavaScript, web geliştiricilerin vazgeçilmez dillerinden biri haline gelmiştir. JavaScript'in bu denli popüler olmasında, sürekli geliştirilen ve yeni özellikler eklenen dil yapısı büyük rol oynar. Proxy, JavaScript'in ES6 ile eklenen güçlü ve esnek özelliklerinden biridir. Bu makalede, JavaScript'de Proxy özelliğinin ne olduğunu, nasıl kullanılacağını ve özellikle hangi amaçlarla kullanıldığını inceleyeceğiz. Ayrıca, JavaScript frameworklerindeki reactive konsepti ile Proxy özelliğini nasıl bağlayabileceğimize dair örnekler de sunacağız.

Proxy Nedir?

JavaScript'de Proxy, bir nesnenin üzerinde yapılan işlemleri özelleştiren ve yöneten bir yapıdır. Başka bir deyişle, Proxy, temel nesnenin üzerinde gerçekleştirilen işlemlere aracılık eder ve bu işlemleri özelleştirebilir. Proxy, nesnelerin üzerinde yapılan işlemleri (okuma, yazma, çağrılma, vb.) yakalama ve müdahale etme yeteneği sunar.

Proxy Kullanımı

Proxy kullanarak bir nesnenin üzerinde gerçekleştirilen işlemleri yönetmek için, ilk olarak bir Proxy nesnesi oluşturmanız gerekir. İşte basit bir örnek:

const target = {
  message: 'Merhaba, Dünya!'
};

const handler = {
  get: function (obj, prop) {
    return obj[prop].toUpperCase();
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message); // "MERHABA, DÜNYA!"

Bu örnekte, target adında bir nesne ve bu nesnenin üzerinde işlemleri yönetecek olan handler adında bir nesne oluşturduk. Ardından, target ve handler nesnelerini kullanarak bir Proxy nesnesi oluşturduk. Proxy nesnesi üzerinden message özelliğine eriştiğimizde, handler nesnesindeki get işlemi devreye girer ve özelliği büyük harflerle döndürür.

Proxy'nin Kullanıldığı Alanlar

Proxy, aşağıdaki senaryolarda kullanılabilir:

  • Veri Doğrulama: Proxy, nesnelerin özelliklerine yazılan değerleri doğrulamak için kullanılabilir.
const user = {
  age: 25
};

const validateHandler = {
  set: function (obj, prop, value) {
    if (prop === 'age' && typeof value !== 'number') {
      throw new TypeError('Yaş değeri bir sayı olmalıdır.');
    }
    obj[prop] = value;
  }
};

const userProxy = new Proxy(user, validateHandler);

userProxy.age = 30; // Başarılı
userProxy.age = 'otuz'; // Hata: TypeError: Yaş değeri bir sayı olmalıdır.

Bu örnekte, user adında bir nesne ve validateHandler adında bir işlem yöneticisi oluşturduk. Proxy nesnesi, age özelliğine yazılacak değeri kontrol eder ve eğer değer sayı değilse hata fırlatır.

  • Değer Dönüşümü: Proxy, nesnelerin özelliklerinin değerlerini dönüştürmek için kullanılabilir.
const temperature = {
  celsius: 25
};

const celsiusToFahrenheitHandler = {
  get: function (obj, prop) {
    if (prop === 'fahrenheit') {
      return (obj.celsius * 9) / 5 + 32;
    }
    return obj[prop];
  }
};

const temperatureProxy = new Proxy(temperature, celsiusToFahrenheitHandler);

console.log(temperatureProxy.fahrenheit); // 77

Bu örnekte, sıcaklık değerlerini içeren bir temperature nesnesi ve bu değerleri dönüştüren celsiusToFahrenheitHandler işlem yöneticisi oluşturduk. Proxy nesnesi, sıcaklık değerini Fahrenheit olarak döndürür.

  • Reaktiflik ile Proxy Kullanımı: Proxy, JavaScript'te reaktif programlama örneklerinde de kullanılabilir ve herhangi bir framework kullanmadan da durum değişikliklerine yanıt olarak işlemleri yönetebilir.
function reactive(obj, callback) {
  const handler = {
    get: function (target, prop) {
      return target[prop];
    },
    set: function (target, prop, value) {
      target[prop] = value;
      callback(prop, value);
      return true;
    }
  };
  return new Proxy(obj, handler);
}

const state = {
  count: 0
};

const render = (prop, value) => {
  console.log(`State değişti: ${prop} = ${value}`);
};

const reactiveState = reactive(state, render);

reactiveState.count++; // State değişti: count = 1
reactiveState.count--; // State değişti: count = 0

Bu örnek, Proxy'nin JavaScript'te reaktif programlama için nasıl kullanabileceğini göstermektedir. Proxy ve işlem yöneticisi kullanarak, nesnelerin özelliklerine yapılan işlemleri yönetebilir ve durum değişikliklerine yanıt olarak geri çağırma işlemlerini tetikleyebiliriz. Bu yaklaşım, geliştiricilere daha fazla esneklik ve kontrol sağlar ve projelerin ihtiyaçlarına göre özelleştirilebilir.

  • Özellik Erişimini İzleme: Proxy, nesnelerin özelliklerine erişimi izlemek ve bu erişimleri raporlamak için kullanılabilir.
const person = {
  name: 'Ahmet',
  age: 30
};

const accessLoggerHandler = {
  get: function (obj, prop) {
    console.log(`"${prop}" özelliğine erişildi.`);
    return obj[prop];
  }
};

const personProxy = new Proxy(person, accessLoggerHandler);

console.log(personProxy.name); // "name" özelliğine erişildi.
console.log(personProxy.age);  // "age" özelliğine erişildi.

Bu örnekte, person adında bir nesne ve bu nesnenin özelliklerine erişimi izleyen accessLoggerHandler işlem yöneticisi oluşturduk. Proxy nesnesi, özelliklere erişildiğinde ilgili bilgileri konsola yazdırır.

  • Özellik Değişikliklerini İzleme: Proxy, nesnelerin özelliklerinde gerçekleştirilen değişiklikleri izlemek ve bu değişiklikleri raporlamak için kullanılabilir.
const product = {
  price: 100
};

const changeLoggerHandler = {
  set: function (obj, prop, value) {
    console.log(`"${prop}" özelliği ${obj[prop]} değerinden ${value} değerine değiştirildi.`);
    obj[prop] = value;
  }
};

const productProxy = new Proxy(product, changeLoggerHandler);

productProxy.price = 120; // "price" özelliği 100 değerinden 120 değerine değiştirildi.

Bu örnekte, product adında bir nesne ve bu nesnenin özelliklerinde gerçekleştirilen değişiklikleri izleyen changeLoggerHandler işlem yöneticisi oluşturduk. Proxy nesnesi, özelliklerdeki değişiklikleri konsola yazdırır.

  • Sanal Özellikler: Proxy, nesnelere sanal (hesaplanmış) özellikler eklemek için kullanılabilir.
const rectangle = {
  width: 10,
  height: 20
};

const areaHandler = {
  get: function (obj, prop) {
    if (prop === 'area') {
      return obj.width * obj.height;
    }
    return obj[prop];
  }
};

const rectangleProxy = new Proxy(rectangle, areaHandler);

console.log(rectangleProxy.area); // 200

Bu örnekte, rectangle adında bir nesne ve bu nesneye sanal bir area özelliği ekleyen areaHandler işlem yöneticisi oluşturduk. Proxy nesnesi, area özelliğine erişildiğinde dikdörtgenin alanını hesaplar ve döndürür.

Proxy özelliği sayesinde, JavaScript'deki nesneler üzerinde güçlü ve esnek işlemler gerçekleştirebilirsiniz. Bu özellik, web uygulamalarının performansını ve güvenliğini artırabilir, kodun okunabilirliğini ve bakımını kolaylaştırabilir. Proxy özelliğini kullanarak, çok sayıda farklı senaryoda işlemleri yönetebilir ve geliştirme sürecini optimize edebilirsiniz.

  • Özellik Adlarını Değiştirme: Proxy, nesnelerin özellik adlarını değiştirerek veya takma adlar oluşturarak kullanmak için kullanılabilir.
const student = {
  firstName: 'Mehmet',
  lastName: 'Yılmaz'
};

const aliasHandler = {
  get: function (obj, prop) {
    if (prop === 'adi') {
      return obj.firstName;
    }
    if (prop === 'soyadi') {
      return obj.lastName;
    }
    return obj[prop];
  }
};

const studentProxy = new Proxy(student, aliasHandler);

console.log(studentProxy.adi);    // Mehmet
console.log(studentProxy.soyadi); // Yılmaz

Bu örnekte, student adında bir nesne ve bu nesnenin özellik adlarını değiştiren aliasHandler işlem yöneticisi oluşturduk. Proxy nesnesi, adi ve soyadi adlarını kullanarak öğrencinin adı ve soyadını döndürür.

  • Özelliklere Varsayılan Değer Atama: Proxy, belirli bir özelliğin değeri belirtilmemişse varsayılan değer atamak için kullanılabilir.
const car = {
  brand: 'Ford',
  model: 'Mustang'
};

const defaultHandler = {
  get: function (obj, prop) {
    return obj[prop] || 'Bilgi yok';
  }
};

const carProxy = new Proxy(car, defaultHandler);

console.log(carProxy.brand);  // Ford
console.log(carProxy.color);  // Bilgi yok

Bu örnekte, car adında bir nesne ve bu nesnenin özelliklerine varsayılan değer atayan defaultHandler işlem yöneticisi oluşturduk. Proxy nesnesi, color özelliğine erişildiğinde değeri olmadığı için 'Bilgi yok' değerini döndürür.

Proxy özelliği, JavaScript dilinin sunduğu güçlü araçlardan biridir ve modern web uygulamalarında daha esnek ve güvenli bir şekilde çalışmanıza olanak tanır. İyi uygulamalarla birlikte, Proxy özelliğini kullanarak uygulamanızın performansını ve kod kalitesini önemli ölçüde artırabilirsiniz. Bu makalede sunulan örnekler, Proxy'nin kullanım alanlarını ve faydalarını göstermektedir; ancak bu özellik, gerçek projelerde daha karmaşık ve özelleştirilmiş senaryolarda kullanılabilir.

  • Fonksiyon Çağrılarını Yönetme: Proxy, fonksiyon çağrılarını yönetmek ve fonksiyonlara ek işlevsellik sağlamak için kullanılabilir.
function greet(name) {
  return `Merhaba, ${name}!`;
}

const timingHandler = {
  apply: function (target, thisArg, argumentsList) {
    console.time('greet');
    const result = target.apply(thisArg, argumentsList);
    console.timeEnd('greet');
    return result;
  }
};

const timedGreet = new Proxy(greet, timingHandler);

console.log(timedGreet('Tayfun')); // Merhaba, Tayfun!

Bu örnekte, greet adında bir fonksiyon ve bu fonksiyonun çağrılma süresini ölçen timingHandler işlem yöneticisi oluşturduk. Proxy nesnesi ile fonksiyonu çağırdığımızda, işlem süresi konsola yazdırılır.

  • Özelliği Okuma ve Yazma İzni Kontrolü: Proxy, nesnelerin belirli özelliklerine erişim izni vererek veya kısıtlayarak kullanılabilir.
const secretData = {
  name: 'John Doe',
  secretKey: '12345'
};

const accessControlHandler = {
  get: function (obj, prop) {
    if (prop === 'secretKey') {
      throw new Error('Bu özelliğe erişim izniniz yok.');
    }
    return obj[prop];
  },
  set: function (obj, prop, value) {
    if (prop === 'secretKey') {
      throw new Error('Bu özelliği değiştirme izniniz yok.');
    }
    obj[prop] = value;
  }
};

const protectedData = new Proxy(secretData, accessControlHandler);

console.log(protectedData.name); // John Doe
console.log(protectedData.secretKey); // Hata: Bu özelliğe erişim izniniz yok.
protectedData.secretKey = '67890'; // Hata: Bu özelliği değiştirme izniniz yok.

Bu örnekte, secretData adında hassas bilgiler içeren bir nesne ve bu nesnenin özelliklerine erişimi yöneten accessControlHandler işlem yöneticisi oluşturduk. Proxy nesnesi ile secretKey özelliğine erişmeye veya değiştirmeye çalıştığımızda hata alırız.

Proxy özelliği, JavaScript'de nesneler ve fonksiyonlar üzerinde yapılan işlemleri özelleştirmenize ve yönetmenize olanak tanır. Bu makalede sunulan örnekler, Proxy'nin çeşitli kullanım alanlarını ve uygulama senaryolarını göstermektedir. Yine de, bu özellik çok daha karmaşık ve özelleştirilmiş durumlar için kullanılabilir ve projelerinize güçlü ve esnek çözümler sunar.

  • Özelliklerin Varlığını Kontrol Etme: Proxy, nesnelerin özelliklerinin varlığını kontrol etmek için kullanılabilir.
const employee = {
  name: 'Ayşe',
  role: 'Developer'
};

const existenceHandler = {
  has: function (obj, prop) {
    if (!(prop in obj)) {
      console.log(`"${prop}" özelliği bulunamadı.`);
      return false;
    }
    return true;
  }
};

const employeeProxy = new Proxy(employee, existenceHandler);

console.log('name' in employeeProxy); // true
console.log('salary' in employeeProxy); // "salary" özelliği bulunamadı. false

Bu örnekte, employee adında bir nesne ve bu nesnenin özelliklerinin varlığını kontrol eden existenceHandler işlem yöneticisi oluşturduk. Proxy nesnesi ile salary özelliğinin varlığını kontrol etmeye çalıştığımızda, konsola mesaj yazdırılır ve false değeri döndürülür.

  • Özelliklerin Sıralamasını Değiştirme: Proxy, nesnelerin özelliklerinin sıralamasını değiştirmek için kullanılabilir.
const items = {
  apple: 5,
  orange: 3,
  banana: 2
};

const sortingHandler = {
  ownKeys: function (obj) {
    return Object.keys(obj).sort((a, b) => obj[a] - obj[b]);
  }
};

const sortedItemsProxy = new Proxy(items, sortingHandler);

console.log(Object.keys(sortedItemsProxy)); // ["banana", "orange", "apple"]

Bu örnekte, items adında bir nesne ve bu nesnenin özelliklerinin sıralamasını değiştiren sortingHandler işlem yöneticisi oluşturduk. Proxy nesnesi ile nesnenin özelliklerini sıraladığımızda, özellikler değerlerine göre artan sırada döndürülür.

  • Proxy ve Reflection: Proxy, JavaScript'teki Reflection API ile birlikte kullanılabilir. Reflection API, nesnelerin yapılarını ve değerlerini programın çalışma süresi boyunca değiştirmenize ve incelemenize olanak tanır. Bu nedenle, Proxy ve Reflection API, nesne ve fonksiyon işlemlerini daha da özelleştirmek ve yönetmek için birlikte kullanılabilir.
const target = {
  name: 'John',
  age: 25
};

const handler = {
  get: function (obj, prop) {
    console.log(`"${prop}" özelliği okunuyor.`);
    return Reflect.get(obj, prop);
  },
  set: function (obj, prop, value) {
    console.log(`"${prop}" özelliği ${value} değeri ile güncelleniyor.`);
    return Reflect.set(obj, prop, value);
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.name); // "name" özelliği okunuyor. John
proxy.age = 26; // "age" özelliği 26 değeri ile güncelleniyor.

Bu örnekte, target adında bir nesne ve bu nesnenin özelliklerine erişimi yöneten handler adında bir işlem yöneticisi oluşturduk. Proxy ile target nesnesine eriştiğimizde, işlem yöneticisi get ve set metodlarını kullanarak özelliklere erişim işlemlerini yönetir.

Özelliklere erişirken, Reflect.get ve Reflect.set işlemlerini kullanarak Reflection API ile birlikte Proxy'yi kullanıyoruz. Bu sayede, nesnelerin özelliklerine yapılan işlemleri daha güçlü ve esnek bir şekilde yönetebiliriz.

Sonuç

Proxy özelliği, JavaScript dilinde güçlü ve esnek bir araçtır. Bu makalede sunulan örnekler, Proxy'nin çeşitli kullanım alanlarını ve uygulama senaryolarını göstermektedir, ancak bu özellik, gerçek projelerde daha karmaşık ve özelleştirilmiş senaryolarda kullanılabilir. Proxy'nin kullanımı ile nesneler ve fonksiyonlar üzerinde yapılan işlemleri yönetebilir, durum değişikliklerine yanıt olarak işlemleri yönetebilir ve uygulamanızın performansını ve esnekliğini önemli ölçüde artırabilirsiniz.

tayfunerbilen
652 gün önce yazdı - 1170 kez görüntülendi.
Önceki Javascript'de Boş Array Oluşturmak Sonraki JavaScript'te Event Loop: Başlangıç Rehberi