ECMAScript 6 sınıflarında alıcılar ve ayarlayıcılar nelerdir?


103

ECMAScript 6 sınıflarında alıcıların ve ayarlayıcıların amacının ne olduğu konusunda kafam karıştı. Amaç ne? Aşağıda bahsettiğim bir örnek var:

class Employee {

    constructor(name) {
        this._name = name;
    }

    doWork() {
        return `${this._name} is working`;
    }

    get name() {
        return this._name.toUpperCase();
    }

    set name(newName){
        if(newName){ 
            this._name = newName;
        }
    }
}

1
C #'dekilere benzer, eğer bunu biliyorsan.
Arturo Torres Sánchez


Bunu açıklayan iyi bir makale şu adreste bulunabilir: coryrylan.com/blog/javascript-es6-class-syntax "Yukarıdaki sınıfımızda ad özelliğimiz için bir alıcı ve ayarlayıcı var. Bir destek alanı oluşturmak için '_' kuralını kullanıyoruz Bizim isim özelliğimizi saklamak için. Bununla birlikte, her get veya set çağrıldığında, bir yığın taşmasına neden olur. JS sınıfları; benim favori sadece typescript kullanıyor, ama ben de Sembol yaklaşımını kullandım
webdevinci

Yanıtlar:


108

Bu ayarlayıcı ve alıcı, özellikleri doğrudan kullanmanıza izin verir (parantez kullanmadan)

var emp = new Employee("TruMan1");

if (emp.name) { 
  // uses the get method in the background
}

emp.name = "New name"; // uses the setter in the background

Bu sadece mülkün değerini ayarlamak ve almak içindir.


1
Nitelik yerine mülk mü demek istediniz? Benim için biraz kafa karıştırıcı
Krizzu

İyi göz Krizzu. Öznitelikler JavaScript'te bulunur ve özelliklerden tamamen farklı şeylerdir. Cevap, niteliklere değil, niteliklere atıfta bulunuyor. Cevabı düzenledim. Cevaplayanın aldıracağını sanmıyorum. :)
Ray Toal

Bunun gerçekten bir avantaj olduğundan pek emin değilim, bir şekilde ayarlayıcı / alıcı kullanma fikrini gizler. Bir sınıfın bir müşterisi, uygun olmadığı durumlarda mülkleri doğrudan kullandığını düşünebilir, ancak bilgi / ayrıntı gizleme ilkesine bağlı olduğunu kabul ediyorum. Belki sonuç olarak bunu kullanırsak, kullanımı kolaylaştırır ve buna daha çok
alışmam

Bir ayarlayıcıda birden fazla parametre geçirebilir misiniz eğer öyleyse onu nasıl kullanıyorsunuz? @David Laberge
Vignesh S

El ile ayarlayıcılar ve alıcılar oluşturmak istiyorsanız, işte coryrylan.com/blog/javascript-es6-class-syntax'tan iyi bir örnek Set: set name(newName) { this._name = newName; }Get:get name() { return this._name.toUpperCase(); }
Jim Doyle

48

ES6'daki toplayıcılar ve ayarlayıcılar diğer dillerde yaptıklarıyla aynı amaca hizmet eder ... ES5 dahil. ES5 Object.defineProperty, daha az temiz ve kullanımı daha zahmetli olsalar da, alıcılara ve ayarlayıcılara zaten izin veriyor .

Etkili bir şekilde, alıcılar ve ayarlayıcılar, okumalar ve yazmalar için standart özellik erişimi gösterimini kullanmanıza izin verirken, yine de özel alıcı ve ayarlayıcı yöntemlerine gerek kalmadan özelliğin nasıl alındığını ve değiştirildiğini özelleştirme yeteneğine sahiptir.

Yukarıdaki Çalışan sınıfında bu, namemülke şu şekilde erişebileceğiniz anlamına gelir :

console.log(someEmployee.name);

Bu olur bakmak normal bir özellik erişim gibi, ama aslında çağırır toUpperCasegeri döndürmeden önce adını. Benzer şekilde, bunu yapmak:

someEmployee.name = null;

ayarlayıcıya erişir ve ayarlayıcısına _nameeklenen koruma cümlesinden dolayı dahili özelliği değiştirmez name.

Ayrıca genel soruya da bakın Neden alıcılar ve ayarlayıcılar kullanılır? Üye erişiminin işlevselliğini değiştirebilmenin neden faydalı olduğu hakkında daha fazla bilgi için.


3

ES6 alıcıları ve ayarlayıcıları, Java'daki benzer kavramlardan önemli ölçüde farklı bir motivasyona sahiptir.

Java'da alıcılar ve ayarlayıcılar, bir sınıfın bir JavaBean tanımlamasına izin verir. Alıcıların ve ayarlayıcıların amacı, fasulyenin genel alanların ima ettiğinden tamamen ortogonal bir "arayüze" sahip olmasına izin vermesidir. Böylece, JavaBean özelliği OLMAYAN bir alan "adı" alabilirim ve alan OLMAYAN bir JavaBean özellik "adresine" sahip olabilirim.

JavaBean özellikleri, Java yansıması aracılığıyla binlerce çerçeve tarafından da (örneğin Hazırda Bekletme) "keşfedilebilir". Bu nedenle, alıcılar ve ayarlayıcılar, fasulye özelliklerini "açığa çıkarmak" için standart bir yöntemin parçasıdır.

Getiriciler ve ayarlayıcılar, işlev olarak, uygulamayı "soyutlama" değerine de sahiptir. EITHER bir alan veya hesaplanmış ("sentetik") bir değer olabilir. Yani "zipcode" adında bir bean özelliğim varsa, bu depolanmış dize olarak başlar. Şimdi, bunu adresten / şehirden / eyaletten hesaplanan bir değer olarak değiştirmek istediğimi varsayalım.

Bir alan kullanırsam, bu kod bozulur:

      String zipcode = address.zipcode();

Ancak bir alıcı kullanırsam, bu bozulmaz:

      String zipcode = address.getZipcode();

JavaScript, JavaBeans gibi bir şeye sahip değildir. Okuduğum kadarıyla, GET ve SET'in amaçlanan değeri yukarıda belirtilen "sentetik" (hesaplanmış) özelliklerle sınırlıdır.

Ancak, Java bir "alanı" bir yönteme uyumlu bir şekilde dönüştürmenize izin vermezken, ES6 GET ve SET buna izin verir.

Yani, eğer sahipsem:

       var zipcode = address.zipcode;

Posta kodunu standart bir nesne özelliğinden bir alıcıya değiştirirsem, yukarıdaki kod artık GET işlevini çağırıyor.

Tanıma GET'i dahil etmezsem, bunun GET posta kodu yöntemini ÇAĞIRMAYACAĞINI unutmayın. Bunun yerine, yalnızca işlevin posta kodunu var.

Bu yüzden bunların, Java ve JavaScript ES6 alıcıları ve ayarlayıcıları arasındaki anlaşılması gereken bazı önemli ayrımlar olduğunu düşünüyorum.


1
class Employee {

    constructor(name) {
      this._name = name;
    }

    doWork() {
      return `${this._name} is working`;
    }

    get name() {
      // when you get this by employeeInstance.mame
      // the code below will be triggered
      // and you can do some logic here
      // just like `console.log` something you want
      console.log('get triggered!')
      return this._name.toUpperCase();
    }

    set name(newName) {
      // the same as `get`
      // when you employeeInstance.mame = 'xxx'
      // the code blew will be trigged
      // and you can also do some logic 
      // like here is a `console.log` and `if check`
      console.log('set triggered!')
      if (newName) {
        this._name = newName;
      }
    }
  }

  const employeeInstance = new Employee('mike')
  employeeInstance.name
  employeeInstance.name = '' // this won't be success, because the `if check`
  console.log(employeeInstance.name)

  // => 
  // get triggered
  // set triggered
  // get triggered
  // MIKE

Her neyse getterve settertıpkı bir casus gibi. Bir nesnenin özelliğini casusluk eder, böylece özelliğin değerini her aldığınızda veya ayarladığınızda bir şeyler yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.