質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

2416閲覧

Javascriptにおいて、外部からアクセスできるプロパティに関してアクセサプロパティを定義する意味とは?

ohs6261

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/05/07 19:49

Javascriptにおける、アクセサプロパティについて。

外部からアクセスできる状態のプロパティに対して、アクセサメソッドを定義する意味はあるのでしょうか。
Javascript Primerで学習中なのですが、このコードを書く意義が分かりません。

javascript

1class NumberWrapper { 2 constructor(value) { 3 this._value = value; 4 } 5 // `_value`プロパティの値を返すgetter 6 get value() { 7 console.log("getter"); 8 return this._value; 9 } 10 // `_value`プロパティに値を代入するsetter 11 set value(newValue) { 12 console.log("setter"); 13 this._value = newValue; 14 } 15} 16 17const numberWrapper = new NumberWrapper(1); 18// "getter"とコンソールに表示される 19console.log(numberWrapper.value); // => 1 20// "setter"とコンソールに表示される 21numberWrapper.value = 42; 22// "getter"とコンソールに表示される 23console.log(numberWrapper.value); // => 42

この場合だと、普通に次のように書けばアクセスできますし、わざわざアクセサは不要なのではないでしょうか。

Javascript

1console.log(numberWrapper._value)

プロパティを外部からアクセスできないようにするにはクロージャを利用すると学んだのですが、この時にはアクセスプロパティを定義する意味はわかります。
しかし、そうでもないのにアクセサプロパティを定義する理由はあるのでしょうか。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/05/07 20:52

コードの出典を明示してください。
guest

回答3

0

ベストアンサー

コーディング規約

現在のECMAScriptにはprivate propertyの機構はない為、名前の先頭or末尾にアンダースコアをつけるコーディング規約が採用されることがあります。

Method names are written in lowerCamelCase. Names for @private methods must end with a trailing underscore.

コログラマは「同命名規則のプロパティを外部から参照しないルール」を遵守する必要があり、性善説の仕組みです。

enumerable: false

Object.defineProperty() で列挙不可能にする事で、外部参照のリスクを下げる事が出来ます。

JavaScript

1'use strict'; 2class NumberWrapper { 3 constructor (value) { 4 Object.defineProperty(this, '_value', { 5 writable: true, 6 configurable: true, 7 value: +value||0 8 }); 9 } 10 valueOf (){ 11 return this._value; 12 } 13} 14 15const nw = new NumberWrapper; 16 17console.log(Object.keys(nw)); // [] 18console.log(Object.getOwnPropertyNames(nw)); // ["_value"] 19console.log(nw, +nw); // NumberWrapper {_value: 0} 0 20nw._value = 1; 21console.log(nw, +nw); // NumberWrapper {_value: 1} 1

WeakMap

WeakMap を使えば、完全なprivate propertyを実装できます。

JavaScript

1'use strict'; 2const NumberWrapper2 = (()=>{ 3 const wm = new WeakMap; 4 5 return class NumberWrapper2 { 6 constructor (value) { 7 wm.set(this, +value||0); 8 } 9 valueOf (){ 10 return wm.get(this); 11 } 12 } 13})(); 14 15 16const nw2 = new NumberWrapper2; 17 18console.log(Object.keys(nw2)); // [] 19console.log(Object.getOwnPropertyNames(nw2)); // [] 20console.log(nw2, +nw2); // NumberWrapper {} 0 21nw2._value = 1; 22console.log(nw2, +nw2); // NumberWrapper {_value: 1} 0

Re: ohs6261 さん

投稿2020/05/08 07:07

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ohs6261

2020/05/09 05:16

非常に納得いくご回答をありがとうございます! 現時点ではあくまで性善説なんですね、privateを実現する方法もあることを知れました!ありがとうございます!
guest

0

外部からアクセスできるプロパティに関してアクセサプロパティを定義する意味

まず 外部からアクセスできるプロパティ の表現ですが、現状、全て public です。

MDN の クラス の説明を読む限り、class ブロックでは 「プライベートフィールド宣言」が説明されており、ブラウザー実装状況 のとおり、少しずつ実装されていますが、すべてのブラウザに対応するには public しか使わない という配慮が必要です。
追記)oikashinoa さんのコメントで示してくださっているリンク先の通り、習慣になっています。

アクセサプロパティを定義する意味 についてですが、JSON.stringify() すると分かります。

アクセサプロパティはJSONのノーテーションに含まれなくなり、オブジェクトの持つ「真に必要なプロパティ名/値」が取り出せます。

javascript

1class NumberWrapper { 2 constructor(value) { 3 this._value = value; 4 } 5 // `_value`プロパティの値を返すgetter 6 get value() { 7 console.log("getter"); 8 return this._value; 9 } 10 // `_value`プロパティに値を代入するsetter 11 set value(newValue) { 12 console.log("setter"); 13 this._value = newValue; 14 } 15 16 // 追記 17 get value2 () { 18 return this._value * 2; 19 } 20} 21 22const numberWrapper = new NumberWrapper(1); 23console.log( JSON.stringify( numberWrapper ) ); 24// { _value: 1 }

追記2)
コード内にアクセサプロパティ value2 を与えてみました。
valuevalue2 をJSONのノーテーションに含めずとも、 _value だけ取り出せれば、「交換用情報」として利用できますので、通信に広く利用されているJSONまで考慮すると圧縮効果があると言えます。

投稿2020/05/07 21:24

編集2020/05/07 21:47
AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ohs6261

2020/05/09 05:19

JSON.stringify()でそのようなことが起こるとは知りませんでした。。 ありがとうございます!
guest

0

スマホからなので簡単に。

以下に書いてあるとおりでは?
[コラム] プライベートプロパティ
https://jsprimer.net/basic/class/#private-property

投稿2020/05/07 21:31

oikashinoa

総合スコア2826

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ohs6261

2020/05/09 05:17

簡潔で明快にありがとうございます。 他の方の回答ともほぼ同じことが書かれていました! 解釈がしっかりとできておりませんでした、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問