Jack Franklin

December 23, 2013

ほとんどの場合、JavaScriptでは、あなたが見るものはあなたが得るものである。 値は値であり、トリックはありません。 たとえば、誰かのフルネームは、彼らの最初と最後の名前の連結です。 もし person オブジェクトがあり、そのオブジェクトのユーザがフルネーム、ファーストネーム、ラストネームを設定でき、その変更が他の値にすぐに反映されるようにしたい場合、従来は

person.setLastName('Smith');person.setFirstName('Jimmy');person.getFullName(); // Jimmy Smith

という関数で構築していました。しかしこれは醜く、オブジェクトのユーザはプロパティが関連しているか気にする必要があり、もっと複雑な例では名前の場合ほど明白ではないかもしれません。 幸運にも、ECMAScript 5 で追加されたより良い方法があります。

ゲッターとセッターを紹介します。 ファーストネーム、ラストネーム、またはフルネームを設定し、他の2つを自動的に更新できるようにしたいと思います。 それらに続くのは、それらが関連するプロパティ (fullName) と、プロパティにアクセス (name = person.fullName) または修正 (person.fullName = 'Some Name') されたときの動作を定義する関数本体です。

これら 2 つのキーワードは、fullName プロパティのゲッターとセッターというアクセッサ関数を定義します。 プロパティにアクセスすると、ゲッターからの戻り値が使用される。 値が設定されると、セッターが呼ばれ、設定された値が渡されます。 その値をどうするかはあなた次第ですが、セッターから返されるのは渡された値です – ですから、何も返す必要はありません。

公式の方法です。 Object.defineProperty

Getter と Setter を宣言するインラインの方法と同様に、Object.defineProperty (MDN Documentation) を使用してより明示的に行うことができます。 このメソッドは 3 つの引数を取ります。 1つ目はプロパティを追加するオブジェクト、2つ目はプロパティの名前、3つ目はプロパティを説明するオブジェクト(プロパティの記述子として知られています)です。 以下は、上記の例を再現した例です。

var person = { firstName: 'Jimmy', lastName: 'Smith'};

Object.defineProperty(person, 'fullName', {get: function() {return firstName + ' ' + lastName;},set: function(name) {var words = name.split(' ');this.firstName = words || '';this.lastName = words || '';}});

ここでの利点はすぐには明らかではありません。 最初のオブジェクトを作成した後にプロパティを追加できること以外に、実際の利点はありますか。

この方法でプロパティを定義すると、セッターまたはゲッターを定義するだけでなく、多くのことを行うことができます。

  • configurable (デフォルトでは false): これが true の場合、プロパティの設定は将来変更可能になります。
  • enumerable (デフォルトでは false): true の場合、オブジェクトをループするときにプロパティが表示されます (for (var key in obj))。

明示的なゲッターやセッターを持たないプロパティも定義できます。

Object.defineProperty(person, 'age', { value: 42});

これは person.age を作成し、それを値 42 に設定します。 このプロパティは書き込み可能でないことに注意することが重要です。 person.age = 99を呼び出しても何の効果もありません。 このようにして、読み取り専用のプロパティを作成することができます。 プロパティにvalueキーが設定されている場合、ゲッターやセッターを持つことはできません。 プロパティは値またはアクセサを持つことができますが、両方を持つことはできません。

それだけでなく、enumerable プロパティのデフォルトは false なので、オブジェクトのキー上をループしても、このプロパティは表示されません。

プロパティを書き込み可能にしたい場合、writable プロパティを設定する必要があります。

Object.defineProperty(person, 'age', { value: 42, writable: true});

これで、person.age = 99; が望ましい効果を発揮します。 ゲッターとセッターにはその使用ケースがありますが、やり過ぎないようにしてください。 慎重に使用すれば、非常に強力です。 しかし、大きな力には大きな責任が伴います。

IE9 以降では、Safari 5+、Firefox 4+、Chrome 5+、および Opera 12+ とともに、Object.defineProperty が完全にサポートされています。 Node.js を使用している場合は、完全なサポートがあります。 Node が大好きでしょう!

この記事は Tom Ashworth との共著です。 この記事をまとめるのに協力してくれた Tom に感謝します。

If you enjoyed this post, join the newsletter to get updates on new content 😎.

All blog posts

If you enjoyed this post, be sure to follow me on Twitter.

Thanks for all blog postsIf you enjoyed the post, continue to follow me on Twitter.

All the blog posts.

コメントを残す

メールアドレスが公開されることはありません。