まずオブジェクト指向的に、隠すべき変数は隠すべきと思っています。
「隠すべき変数は隠すべき」ですが、「車は車です」といっているような違和感が…。
まず、**なぜインスタンスプロパティを隠すべきか?**を考えてみてはどうでしょうか?
私としては「隠すべき理由」に「意図せずに書き換えられて他のプロパティとの整合性が取れなくなる」があげられると考えます。
ただし、全てのプロパティを隠すべきとは思いませんし、ECMAScript ではいくつかの解が設けられています。
Array#length
は公開されていますが、length
プロパティを書き換えると配列の要素数も書き換わる(setter)為、問題なく機能します。
JavaScript
1var array = [1, 2, 3, 4, 5];
2array.length = 1;
3console.log(array); // [1]
Function#length
は公開されていますが、length
プロパティは読み取り専用の為、不正に書き換わることはありません。
JavaScript
1function sum (a, b) { return a + b; }
2sum.length = 3; // TypeError: Cannot assign to read only property 'length' of function sum(a, b) { return a + b; }
3console.log(sum.length); // 2
4console.log(Object.getOwnPropertyDescriptor(sum, 'length')); // Object {value: 2, writable: false, enumerable: false, configurable: true}
Array.prototype
を拡張すると for-in
で拡張した Array.prototype
上のプロパティが列挙される(いわゆる Array.prototype
汚染)がありますが、既存の Array.prototype.slice
等は for-in
で列挙されません。
なぜなら、Array.prototype.slice
は列挙不可能(enumerable === false)だからです。
JavaScript
1var array = [], keys = [];
2for (key in array) { // enumerable なプロパティは列挙しない
3 keys.push(key);
4}
5console.log(keys); // []
6console.log(Object.getOwnPropertyDescriptor(Array.prototype, 'slice')); // {writable: true, enumerable: false, configurable: true}
いずれも、Object.defineProperty
を使うことで実装可能です。
Object.defineProperty
は IE7 で使えず、IE8 で DOM ノードにしか使えない機能制約がある為、事実上、IE9+ が対象ブラウザでなければ使えません。
制作ポリシーによっては2016/01/12までは使えない判断もあると思います。
どうしても、プライベートプロパティが必要であれば、ES6 の WeakMap
を使用する事で実装可能です。
WeakMap
は ES3 の範囲内でも polyfill を書くことが出来る為、現在でも十分に実用的です。
JavaScript
1var Hoge = (function () {
2 var privateMap = new WeakMap;
3
4 function Hoge (x, y) {
5 privateMap.set(this, {x: Number(x), y: Number(y)});
6 }
7
8 Object.defineProperty(Hoge.prototype, 'sum', {writable: true, configurable: true, enumerable: false, value: function sum () {
9 var obj = privateMap.get(this);
10
11 return obj.x + obj.y;
12 }});
13
14 return Hoge;
15})();
16
17var hoge = new Hoge(2, 4);
18
19console.log(hoge.sum()); // 6
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/10/20 03:18
2015/10/20 08:51 編集
2015/10/20 05:11