Apa getter dan setter untuk kelas ECMAScript 6?

102

Saya bingung apa gunanya getter dan setter di kelas ECMAScript 6. Apa tujuannya? Di bawah ini adalah contoh yang saya maksud:

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;
        }
    }
}
TruMan1
sumber
1
Ini mirip dengan yang ada di C #, jika Anda kebetulan mengetahuinya.
Arturo Torres Sánchez
Artikel bagus yang menjelaskan hal ini dapat ditemukan di: coryrylan.com/blog/javascript-es6-class-syntax "Di kelas kami di atas, kami memiliki pengambil dan penyetel untuk properti nama kami. Kami menggunakan konvensi '_' untuk membuat bidang dukungan untuk menyimpan properti nama kita. Tanpa ini setiap kali get atau set dipanggil, itu akan menyebabkan stack overflow "... Ini juga berbicara tentang variabel yang tidak benar-benar 'pribadi', tetapi ada banyak cara baru untuk membuat vars pribadi di Kelas JS; favorit saya hanya menggunakan Ketikan, tetapi saya juga telah menggunakan pendekatan Simbol
webdevinci

Jawaban:

108

Penyetel dan pengambil ini memungkinkan Anda untuk menggunakan properti secara langsung (tanpa menggunakan tanda kurung)

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

Ini hanya untuk mengatur dan mendapatkan nilai properti.

David Laberge
sumber
1
Apakah yang Anda maksud adalah properti, bukan atribut? Agak membingungkan bagi saya
Krizzu
Mata yang bagus, @Kriyu. Atribut ada di JavaScript dan merupakan hal yang sama sekali berbeda dari properti. Jawabannya memang mengacu pada properti, bukan atribut. Saya sudah mengedit jawabannya. Saya tidak berpikir penjawab akan keberatan. :)
Ray Toal
Saya tidak begitu yakin ini benar-benar keuntungan, entah bagaimana menyembunyikan gagasan menggunakan setter / getter. Seorang klien kelas mungkin berpikir itu secara langsung menggunakan properti, yang tidak sesuai, tapi saya setuju itu mematuhi prinsip penyembunyian informasi / detail. Mungkin jika kita menggunakan ini sebagai konsekuensinya, itu membuat penggunaan lebih mudah dan saya hanya harus lebih terbiasa ...
Christof Kälin
Bisakah Anda melewatkan beberapa parameter dalam satu penyetel jika demikian, bagaimana Anda menggunakannya? @David Laberge
Vignesh S
Jika Anda ingin membuat setter dan getter secara manual, berikut adalah contoh yang bagus dari coryrylan.com/blog/javascript-es6-class-syntax Set: set name(newName) { this._name = newName; }Get:get name() { return this._name.toUpperCase(); }
Jim Doyle
48

Getters dan setter di ES6 memiliki tujuan yang sama dengan yang mereka lakukan dalam bahasa lain ... termasuk ES5. ES5 sudah mengizinkan getter dan setter lewat Object.defineProperty, meskipun mereka kurang bersih dan lebih rumit untuk digunakan.

Secara efektif, getter dan setter memungkinkan Anda menggunakan notasi akses properti standar untuk membaca dan menulis sambil tetap memiliki kemampuan untuk menyesuaikan cara properti diambil dan dimutasi tanpa perlu metode pengambil dan penyetel eksplisit.

Di kelas Karyawan di atas, ini berarti Anda dapat mengakses nameproperti seperti ini:

console.log(someEmployee.name);

Ini akan terlihat seperti akses properti normal, tetapi sebenarnya akan memanggil toUpperCasenama sebelum mengembalikannya. Demikian pula, melakukan ini:

someEmployee.name = null;

akan mengakses setter, dan itu tidak akan mengubah _nameproperti internal karena klausa penjaga diperkenalkan di namesetter.

Lihat juga pertanyaan umum Mengapa menggunakan getter dan setter? untuk informasi lebih lanjut tentang mengapa bisa mengubah fungsionalitas akses anggota itu berguna.

Alexis King
sumber
3

Getter dan setter ES6 memiliki motivasi yang jauh berbeda dari konsep serupa di Java.

Di Java, getter dan setter mengizinkan kelas untuk mendefinisikan JavaBean. Inti dari getter dan setter adalah memungkinkan bean memiliki "antarmuka" ortogonal sepenuhnya dari yang tersirat oleh field publik. Jadi saya dapat memiliki sebuah field "name" yang BUKAN merupakan property JavaBean, dan saya dapat memiliki sebuah property "address" JavaBean yang BUKAN sebuah field.

Properti JavaBean juga "dapat ditemukan" oleh ribuan kerangka kerja (Hibernate misalnya) melalui refleksi Java. Jadi, getter dan setter adalah bagian dari metode standar untuk "mengekspos" properti bean.

Getter dan setter, sebagai fungsi, juga memiliki nilai yang "mengabstraksikan" implementasi. Ini bisa SALAH SATU bidang atau nilai yang dihitung ("sintetik"). Jadi jika saya memiliki properti kacang yang disebut "kode pos", itu dimulai sebagai string yang disimpan. Sekarang misalkan saya ingin mengubahnya menjadi nilai yang dihitung dari alamat / kota / negara bagian?

Jika saya menggunakan bidang, kode ini rusak:

      String zipcode = address.zipcode();

Tetapi jika saya menggunakan getter, ini tidak akan rusak:

      String zipcode = address.getZipcode();

JavaScript tidak memiliki yang seperti JavaBeans. Sejauh yang saya baca, nilai GET dan SET yang dimaksudkan terbatas pada properti "sintetik" (dihitung) tersebut di atas.

Tapi itu agak lebih baik daripada java karena Java tidak memungkinkan Anda untuk secara kompatibel mengubah "field" menjadi metode, ES6 GET dan SET memungkinkannya.

Artinya, jika saya memiliki:

       var zipcode = address.zipcode;

Jika saya mengubah kode pos dari properti objek standar menjadi pengambil, kode di atas sekarang memanggil fungsi GET.

Perhatikan bahwa jika saya tidak menyertakan GET dalam definisi, ini TIDAK akan memanggil metode GET kode pos. Sebagai gantinya, itu hanya akan menetapkan kode pos fungsi ke var.

Jadi menurut saya ini adalah beberapa perbedaan penting untuk dipahami antara getter dan setter Java dan JavaScript ES6.

DaBlick
sumber
0
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

Pokoknya getterdan setteritu seperti mata-mata. Ini memata-matai properti suatu objek, sehingga Anda dapat melakukan sesuatu, setiap kali Anda mendapatkan atau menetapkan nilai properti.

RandomYang
sumber