2017-01-29 6 views
1

私は、新しいECMAScript 2015 JavaScriptクラスを使用して、hereというメールクラスを定義することを試みています。新しいECMAScript 2015 JavaScriptクラスでゲッタとセッタを定義する方法

私はこのコンストラクタを思い付いたし、次のゲッター試してみました:

class Mail { 
    constructor(sender, date, subject, text) { 
     this.sender = sender; 
     this.date = date; 
     this.subject = subject; 
     this.text = text; 
    } 
    get sender() { 
     return this.sender; 
    } 
} 

をしかし、私は、そのメソッドを使用しようとしたとき、それは動作しませんでした。

TypeError: mail.sender is not a function 

だから、私の疑問は次のとおりです:

  1. は、Javaのようにゲッターとセッターを定義することが必要ですか私は単にmail.sender(かそこらのようなフィールドにアクセスすることができます返さ

    var mail = new Mail("@mail.com", Date.now(), "Testing", "Text"); 
    console.log(mail.sender()); 
    

    )?

  2. ゲッターとセッターをそれぞれのクラスインスタンス変数に適切に定義する方法が必要な場合は、
+0

ゲッターとセッターを使用するには、あなただけのプロパティを使用して設定する必要があります。 'mail.sender' – nicovank

+0

@nicovank私は必要なメールプロパティに直接アクセスできますか?どのようなカプセル化の問題など、Javaでそうではありませんか? –

+0

'mail.sender'を現在の状態で実行すると、無限再帰が発生します。 –

答えて

0

ゲッターとセッターを使用するには、単に使用してプロパティを設定する必要があります。あなたの場合:mail.sender。これは、値を使用している場合はゲッターを呼び出し、現在の値をオーバーライドする場合はセッターを呼び出します。

class Mail { 
 
    constructor(sender) { 
 
     this._sender = sender; 
 
    } 
 

 
    get sender() { 
 
     return "Sender: " + this._sender; 
 
    } 
 

 
    set sender(val) { 
 
     this._sender = val.toLowerCase(); 
 
    } 
 
} 
 

 
const m = new Mail("TEST"); 
 
console.log(m.sender); // => "Sender: TEST" 
 

 
m.sender = "TEST"; 
 
console.log(m.sender); // => "Sender: test"

IはMaximum call stack size exceeded errorを防止するために値を格納する_senderを使用注意。

他のプロパティと同様にプロパティを使用できます。自動的にgetterまたはsetterが呼び出されます。あなたが探していたことはカプセル化がある場合


、あなたはそうのようなあなたのクラスを設計できます。この場合

const Mail = (function() { 
    let sender; // this is "private" 

    return { 
     title: "public", // This is public 
     get sender() { 
      return sender; 
     }, 
     // ... 
    }; 
}); 

は、あなたがそのようにように新しい Mailオブジェクトを作成します。

const mail = Mail(); 

newキーワードを使用して新しいオブジェクトをインスタンス化できるようにするには、Mail関数で関数を返すことができます。

+0

モジュールパターンでは、新しいオブジェクトを作成できません。そのためには工場出荷時のパターン – NonPolynomial

+0

@ NonPolynomialがあります。私は編集します。 – nicovank

4

ゲッターとセッターは、基本的プロパティオブジェクトのためGET-及びセット - アクションを捕捉するためにフックされています。それらは関数ですが、(このオブジェクトを使用するコードに)と表示されますは、プロパティのようです。

var mail = new Mail("@mail.com", Date.now(), "Testing", "Text"); 
console.log(mail.sender); //no brackets 

セッターを追加すると、main.sender = "@foo.bar"が追加されます。

そして、自分のゲッターが呼び出されて以来、あなたのコードが無限回帰で詰まっていないのではないかと思います。

class Mail { 
    constructor(sender, date, subject, text) { 
     this._sender = sender; 
     this._date = date; 
     this._subject = subject; 
     this._text = text; 
    } 

    //this IS `this.sender`! 
    //it should not `return this.sender`, since this would call this getter again, 
    //and you get stuck in an infinite recursion. 
    get sender() { 
     return this._sender; 
    } 

    //and a possible setter, that handles 
    //instance.sender = whatever; 
    set sender(value) { 
     this._sender = value; 
    } 
} 

編集:

が、これは私が直接オブジェクトのフィールドにアクセスすることができますので、私はちょうどgetおよびsetメソッドを無視することができることを意味するのでしょうか?

JSでプロパティをパブリックにする必要はありません。このプロパティを定義するだけで、パブリックが利用できるようになります。 JSは別の方法で動作します。物事を非公開にするためにさらに努力する必要があります(締め切りを参照)。 JSでは、すべてがデフォルトで公開されています。

しかし、あなたは次のように、追加のタスクを満たすためにゲッター(およびセッター)を使用することができます。

class Person{ 
    constructor(firstName, lastName){ 
     //regular public properties 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    //a composed value, that you can access like a property 
    get fullName(){ 
     return this.firstName + " " + this.lastName; 
    } 

    //you could also add a setter like this 
    set fullName(value){ 
     [this.firstName, this.lastName] = value.split(/\s+/g); 
    } 
} 

var john = new Person("John", "Doe"); 
console.log(john.fullName); 
+0

結局のところ、無限の再帰でそれは本当に止まってしまいます。これは、オブジェクトフィールドに直接アクセスできるので、getメソッドとsetメソッドを無視できるということですか? (無限再帰で詰まっていない唯一の方法は、get/setの名前を変更する場合です) –

+0

@rcbauerはい、値を保持する単純なプロパティが必要な場合は、getters/setterは必要ありません。 – Pointy

+0

@rcbauerあなたのゲッターが 'sender(){return this.sender;を返すので、それは無限の再汚染の中で立ち往生します。 } '自身が呼び出しています。 'return this.sender'はゲッターをもう一度呼びます。そのため、私はアンダースコア(これはJSの共通のパターンです)でプロパティをプリペンドしました。アンダースコアで始まるプロパティはプライベートであり、APIの一部ではありません。 – Thomas

0

あなたが実際にあなたがする必要以上のことをやりました。指定したゲッターは必要ありません。

これを試してみてください:

class Mail { 
constructor(sender, date, subject, text) { 
    this.sender = sender; 
    this.date = date; 
    this.subject = subject; 
    this.text = text; 
    } 
} 

var mail = new Mail("@mail.com", Date.now(), "Testing", "Text"); 
console.log(mail.sender); 
0

JavaScriptにはクラスの概念がありません。 classというキーワードは構文的な砂糖です。

classとは何ですか?constructor functionを生成します。

const Person = class { // or `class Person` 
    constructor(name) { 
     this.name = name; 
    } 

    say(msg) { 
     return `${this.name} says: "${msg}".`; 
    } 
} 

これはまったく同じです。これは、次のコードで達成するものと同じです。

const Person = function(name) { 
    this.name = name; 
}; 

Person.prototype = { 
    say(msg) { 
     return `${this.name} says: "${msg}".`; 
    } 
}; 

プライベート変数が必要な場合は、クロージャを使用する必要があります。あなたがclassを使用しないようにとnewを避けるために

const Person = class { // or `class Person` 
    constructor(name) { 
     this.getName =() => name; 
     this.setName = (newName) => { 
      name = newName; 
     } 
    } 

    say(msg) { 
     return `${this.getName()} says: "${msg}".`; 
    } 
} 

let p = new Person('me'); 
console.log(p.name); // undefined 
console.log(p.getName()); // 'me' 
p.setName('he'); 
console.log(p.getName()); // 'he' 
console.log(p.say('something')); // 'he says: "something".' 

Iのアドバイス。あなたがオブジェクトが必要な場合は 、あなたは単にfactory functionsを使用することができます。

const Person = function(name) { 
    let person = Object.create(Person.prototype); 
    person.name = name; 
    return person; 
}; 

Person.prototype = { 
    say(msg) { 
     return `${this.name} says: "${msg}".`; 
    } 
}; 
関連する問題