ECMAScript 6クラスのゲッターとセッターは何ですか?


102

ECMAScript 6クラスのゲッターとセッターのポイントが何なのか混乱しています。目的は何ですか?以下は私が言及している例です:

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#のものに似ています。
Arturo


これだけを説明する良い記事は、次の場所にあります。名前プロパティを保存します。これがないと、getまたはsetが呼び出されるたびに、スタックオーバーフローが発生します。...また、変数が本当に「プライベート」ではないことを示しますが、プライベート変数をJSクラス; 私のお気に入りは
Typescriptを

回答:


108

これらのセッターおよびゲッターを使用すると、プロパティを直接(括弧を使用せずに)使用できます。

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

これは、プロパティの値を設定および取得するためだけのものです。


1
属性の代わりにプロパティを意味しましたか?私を少し混乱させる
Krizzu

@Krizzuよろしくお願いします。属性はJavaScriptに存在し、プロパティとはまったく異なります。答えは確かに属性ではなくプロパティを参照しています。回答を編集しました。回答者は気にしないと思います。:)
Ray Toal

これが本当にこのような利点であることはよくわかりません。セッター/ゲッターを使用するという概念を何らかの形で隠しています。クラスのクライアントは、適切ではないプロパティを直接使用していると思うかもしれませんが、情報/詳細の非表示の原則に準拠していることに同意します。たぶんこれを使用すると、使用が簡単になり、慣れる必要があります...
ChristofKälinJun

複数のパラメーターをセッターで渡すことができる場合、どのように使用しますか?@David Laberge
Vignesh S

セッターとゲッターを手動で作成したい場合は、coryrylan.com / blog / javascriptset name(newName) { this._name = newName; }get name() { return this._name.toUpperCase(); }
Jim Doyle

48

ES6のゲッターとセッターは、ES5を含む他の言語と同じ目的を果たします。ES5では既にを介してゲッターとセッターを使用できObject.definePropertyますが、クリーン度が低く、使用が面倒です。

効果的に、ゲッターとセッターを使用すると、明示的なゲッターメソッドとセッターメソッドを必要とせずにプロパティの取得方法と変更方法をカスタマイズしながら、読み取りと書き込みに標準のプロパティアクセス表記を使用できます。

上記のEmployeeクラスでは、次のnameようにプロパティにアクセスできます。

console.log(someEmployee.name);

これは通常のプロパティアクセスのように見えますが、実際toUpperCaseには返される前に名前を呼び出します。同様に、これを行う:

someEmployee.name = null;

はセッターにアクセスし、のセッターで_name導入されたガード句のため、内部プロパティを変更しませんname

一般的な質問も参照してください。なぜゲッターとセッターを使用するのですか?メンバーアクセスの機能を変更できると便利な理由の詳細については。


3

ES6のゲッターとセッターは、Javaの同様の概念とは実質的に異なる動機を持っています。

Javaでは、ゲッターとセッターを使用してクラスでJavaBeanを定義できます。ゲッターとセッターのポイントは、それにより、Beanが、パブリックフィールドによって暗示されるものから完全に直交する「インターフェース」を持つことができるようになることです。したがって、JavaBeanプロパティではないフィールド「name」を使用でき、フィールドではないJavaBeanプロパティ「address」を使用できます。

JavaBeanプロパティは、Javaリフレクションを介して数千のフレームワーク(Hibernateなど)によって「検出可能」です。したがって、ゲッターとセッターは、Beanプロパティを「公開」するための標準メソッドの一部です。

関数であるゲッターとセッターにも、実装を「抽象化」するという価値があります。フィールドまたは計算された(「合成」)値のどちらでもかまいません。したがって、「zipcode」というBeanプロパティがある場合、それは保存された文字列として始まります。ここで、住所/都市/州から計算された値に変更したいとしますか?

フィールドを使用すると、このコードは壊れます。

      String zipcode = address.zipcode();

しかし、ゲッターを使用しても、これは壊れません:

      String zipcode = address.getZipcode();

JavaScriptにはJavaBeansのようなものはありません。私が読んだ限りでは、GETおよびSETの意図された値は、前述の「合成」(計算された)プロパティに制限されています。

ただし、Javaでは「フィールド」をメソッドに互換的に変換することはできませんが、ES6のGETおよびSETでは可能です。

つまり、私が持っている場合:

       var zipcode = address.zipcode;

郵便番号を標準のオブジェクトプロパティからゲッターに変更すると、上記のコードでGET関数が呼び出されます。

定義にGETを含めなかった場合、郵便番号のGETメソッドが呼び出されないことに注意してください。代わりに、関数zipcodeを変数に割り当てるだけです。

したがって、これらはJavaとJavaScript ES6のゲッターとセッターの間で理解するためのいくつかの重要な違いだと思います。


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

とにかくgettersetterちょうどスパイのようなものです。オブジェクトのプロパティをスパイし、プロパティの値を取得または設定するたびに何かを実行できるようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.