teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

setterの部分を修正[未定義のPropertyの場合、処理しない様に修正]

2020/10/12 02:50

投稿

tama_yn0815
tama_yn0815

スコア143

title CHANGED
File without changes
body CHANGED
@@ -62,38 +62,142 @@
62
62
 
63
63
  ### 最終的に出来上がったソースコード
64
64
  ```javascriot
65
+ (function () {
66
+ // 基底セッター
65
- Object.prototype.setter = function(member, /*...multilayered, */value) {// -> member, multilayered, vは実質使用しない....残余引数で対応したい
67
+ Object.prototype.setter = function(member, /*...multilayered, */value) {// -> member, multilayered, valueは実質使用しない....残余引数で対応したい
66
- var _obj = this;// -> Class化されたオブジェクトに対応
68
+ var obj = this;// -> Class化されたオブジェクトに対応
67
- // 通常配列化
69
+ // 通常配列化
68
- var _args = Array.from(arguments); // -> ポリフィルを作成した(IEとか対応)
70
+ var _args = Array.from(arguments); // -> ポリフィルを作成した(IEとか対応)
69
- if (_args.length < 2) {
71
+ if (_args.length < 2) {
70
- var msg = 'Unexpected execution: there are not enough arguments to execute ' + typeof this + '.';
72
+ var msg = 'Unexpected execution: there are not enough arguments to execute ' + typeof this + '.';
71
- throw new UserException(msg, 'error'); // -> typeは列挙型にしたい
73
+ throw new TypeError(msg);
72
- }
74
+ }
73
- var changeAssignValue = _args.pop(); // -> _argsから最後の要素を削除し、変数[changeAssignValue]でキャッチする
75
+ var changeAssignValue = _args.pop(); // -> _argsから最後の要素を削除し、変数[changeAssignValue]でキャッチする
74
- var menberKeyList = getMenberKeyList(_args.flat(1/0)); //-> _argsの中身を単配列化&階層を配列に詰める
76
+ var menberKeyList = getMenberKeyList(_args.flat(1/0)); //-> _argsの中身を単配列化&階層を配列に詰める
75
- var menberLayeredLength = menberKeyList.length;
77
+ var menberLayeredLength = menberKeyList.length;
76
- var menberListIndex = 0;
78
+ var menberListIndex = 0;
77
- var hasMenber = false;
79
+ var hasMenber = false;
78
- var memberName = void(0);
80
+ var memberName = void(0);
79
- var o = _obj; // -> 処理用変数
81
+ var _obj = obj; // -> 処理用変数
80
- var isLast = false;
82
+ var isLast = false;
81
- while (menberListIndex < menberLayeredLength) {
83
+ while (menberListIndex < menberLayeredLength) {
82
- isLast = (menberListIndex == menberLayeredLength - 1);
84
+ isLast = (menberListIndex == menberLayeredLength - 1);
83
- memberName = menberKeyList[menberListIndex];
85
+ memberName = menberKeyList[menberListIndex];
84
- hasMenber = o.hasOwnProperty(memberName); // -> _objではダメ。。1階層目以外書き換え不可
86
+ hasMenber = _obj.hasOwnProperty(memberName); // -> objではダメ。。1階層目以外書き換え不可
85
- if (hasMenber) {
87
+ if (hasMenber) {
86
- // 最後のindexのみ、propertyの書き換え
88
+ // 最後のindexのみ、propertyの書き換え
87
- if (isLast) {
89
+ if (isLast) {
88
- Object.defineProperty(o, memberName, { value: changeAssignValue, writable: false, enumerable: true });
90
+ Object.defineProperty(_obj, memberName, { value: changeAssignValue, writable: false, enumerable: true });
91
+ }
92
+ _obj = _obj[memberName];
93
+ } else {
94
+ //_obj[memberName] = {};// -> 不用意なメンバー追加は避けた方が良いかも。。。
89
95
  }
90
- } else {
96
+ menberListIndex++;
91
- o[memberName] = {};// -> 不用意なメンバー追加は避けた方が良いかも。。。
92
97
  }
98
+ return obj;
99
+ };
100
+ // 念のため、列挙不可へ書き換え...jQueryUIの処理とバッティングする
101
+ Object.defineProperty(Object.prototype, 'setter', { value: Object.prototype.setter, writable: false, enumerable: false });
102
+
103
+ // 基底ゲッター
104
+ Object.prototype.getter = function(member/*, ...multilayered*/){// -> m, multilayeredは実質使用しない....残余引数で対応
105
+ var obj = this;// -> Class化されたオブジェクトに対応
106
+ // 通常配列化
107
+ var _args = Array.from(arguments); // -> ポリフィルを作成した(IEとか対応)
108
+ if (_args.length < 1) {
109
+ var msg = 'Unexpected execution: there are not enough arguments to execute ' + typeof this + '.';
110
+ throw new TypeError(msg);
111
+ }
112
+ var results = null;
113
+ var menberKeyList = getMenberKeyList(_args.flat(1/0)); //-> _argsの中身を単配列化&階層を配列に詰める
114
+ var menberLayeredLength = menberKeyList.length;
115
+ var menberListIndex = 0;
116
+ var hasMenber = false;
117
+ var memberName = void(0);
118
+ var _obj = obj; // -> 処理用変数
119
+ while (menberListIndex < menberLayeredLength) {
120
+ isLast = (menberListIndex == menberLayeredLength - 1);
121
+ memberName = menberKeyList[menberListIndex];
122
+ hasMenber = _obj.hasOwnProperty(memberName); // -> objではダメ。。1階層目以外書き換え不可
123
+ if (hasMenber) {
124
+ if (isLast) {
125
+ results = _obj[memberName];
126
+ }
93
- o = o[memberName];
127
+ _obj = _obj[memberName];
128
+ }
94
- menberListIndex++;
129
+ menberListIndex++;
95
- }
130
+ }
131
+ return results;
132
+ };
133
+ // 念のため、列挙不可へ書き換え...jQueryUIの処理とバッティングする
134
+ Object.defineProperty(Object.prototype, 'getter', { value: Object.prototype.getter, writable: false, enumerable: false });
135
+
136
+ // Array[ポリフィル:IE11対応]
137
+ Object.defineProperty(Array.prototype, 'flat', { writable: false, enumerable: false, value: (function (){
138
+ return (Array.prototype.flat) ? Array.prototype.flat : function (deepth) {
139
+ var _arr = this;
140
+ if (isNaN(deepth)) { deepth = 1; }
141
+ return deepth > 0 ? _arr.reduce(function (acc, val) {
142
+ return acc.concat(Array.isArray(val) ? val.flatDeep(deepth - 1) : val);
143
+ }, []) : _arr.slice();
144
+ };
145
+ })()});
146
+ Object.defineProperty(Array, 'from', { writable: false, enumerable: false, value: (function () {
147
+ return (Array.from) ? Array.from : function (arrayLike/*, mapFn, thisArg */) {
148
+ var arr = this;
149
+ var items = Object(arrayLike);
150
+ if (arrayLike == null) {
151
+ throw new TypeError('Array.from requires an array-like object - not null or undefined');
152
+ }
153
+ var mapFn = arguments.length > 1 ? arguments[1] : void undefined;// -> 受け取った場合はそれを使う
154
+ var _this;
155
+ if (typeof mapFn !== 'undefined') {
156
+ if (!isCallable(mapFn)) {
157
+ throw new TypeError('Array.from: when provided, the second argument must be a function');
158
+ }
159
+ if (arguments.length > 2) {
160
+ _this = arguments[2];
161
+ }
162
+ }
163
+ var len = toLength(items.length);
164
+ var Arr = isCallable(arr) ? Object(new arr(len)) : new Array(len);
165
+ var index = 0;
166
+ var item;
167
+ while (index < len) {
168
+ item = items[index];
169
+ if (mapFn) {
170
+ Arr[index] = typeof _this === 'undefined' ? mapFn(item, index) : mapFn.call(_this, item, index);
171
+ } else {
172
+ Arr[index] = item;
173
+ }
174
+ index += 1;
175
+ }
176
+ Arr.length = len;
96
- return _obj;
177
+ return Arr;
178
+ };
179
+ // 秘匿関数
180
+ function isCallable (fn) {
181
+ return typeof fn === 'function' || Object.prototype.toString.call(fn) === '[object Function]';
182
+ }
183
+ function toInteger (value) {
184
+ var number = Number(value);
185
+ if (isNaN(number)) {
186
+ return 0;
187
+ }
188
+ if (number === 0 || !isFinite(number)) {
189
+ return number;
190
+ }
191
+ return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
192
+ }
193
+ function toLength (value) {
194
+ var maxSafeInteger = Math.pow(2, 53) - 1; // 2^53-1 約9千兆
195
+ var len = toInteger(value);
196
+ return Math.min(Math.max(len, 0), maxSafeInteger);
197
+ };
198
+ })()});
199
+
200
+ /** 秘匿関数 */
97
201
  // 階層を順番に並び替えて返却(単配列化)
98
202
  function getMenberKeyList (obj) {
99
203
  return (!Array.isArray(obj) || obj.length < 1) ? [] : (function (r, o) {
@@ -109,34 +213,27 @@
109
213
  return r;
110
214
  })([], obj);
111
215
  }
216
+ /** under test code */
112
- };
217
+
113
-
114
- // -> test code type Array
218
+ // -> test code setter by type Array.
115
- var nestedArray = [[[[[[1,2,3]]]]]];
219
+ var nestedArray = [[[[[[1,2,3]]]]]];
116
- console.log(nestedArray); // -> [0: [0: [0: [0: [0: [0: 1. 1: 2, 2: 3]]]]]];
117
- nestedArray.setter('0.0.0.0.0.1',5);
118
- console.log(nestedArray); // -> [0: [0: [0: [0: [0: [0: 1. 1: 5, 2: 3]]]]]];
220
+ console.log(nestedArray.setter('0.0.0.0.0.1',5)); // -> [0: [0: [0: [0: [0: [0: 1. 1: 5, 2: 3]]]]]];
119
-
120
- // -> test code type Object
221
+ // -> test code setter by type Object.
121
- var nestedObject = {a: {b: {c: {d: {e: 'hoge', z: 'fuga'}}}}};
222
+ var nestedObject = {a: {b: {c: {d: {e: 'hoge', z: 'fuga'}}}}};
122
- console.log(nestedObject); // -> {a: {b: {c: {d: {e: 'hoge', z: 'fuga'}}}}};
123
- nestedObject.setter('a.b','c',['d','e'],'hogehoge');
124
- console.log(nestedObject); // -> {a: {b: {c: {d: {e: 'hogehoge', z: 'fuga'}}}}};
223
+ console.log(nestedObject.setter('a.b','c',['d','e'],'hogehoge')); // -> {a: {b: {c: {d: {e: 'hogehoge', z: 'fuga'}}}}};
125
-
126
- // -> test code type Instance
224
+ // -> test code setter by type Instance.
127
- var _func = function _func () {
128
- this.mem1 = {};
129
- this.mem1.mem2 = {};
130
- this.mem1.mem2.mem3 = {};
131
- this.mem1.mem2.mem3.mem4 = {};
132
- this.mem1.mem2.mem3.mem4.mem5 = 'member5';
225
+ var _func = function _func () { this.mem1 = {mem2: {mem3: {mem4: {mem5: 'member5', mem6: 'member6'}}}}; };
133
- this.mem1.mem2.mem3.mem4.mem6 = 'member6';
134
- }
135
- var nestedPropIns = new _func();
226
+ var nestedPropIns = new _func();
136
- console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: 'member5', mem6: 'member6'}}}}};
137
- nestedPropIns.setter('mem1.mem2.mem3.mem4.mem5', '12345');
138
- console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: '12345', mem6: 'member6'}}}}};
227
+ console.log(nestedPropIns.setter('mem1.mem2.mem3.mem4.mem5', '12345')); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: '12345', mem6: 'member6'}}}}};
228
+
229
+ // -> test code getter by type Array.
230
+ console.log(nestedArray.getter('0.0.0.0.0.1'));// -> 5
231
+ console.log(nestedArray.getter('0.0.0.0.0.4'));// -> null
232
+ // -> test code getter by type Object.
233
+ console.log(nestedObject.getter('a.b','c',['d','e'])); // -> hogehoge
234
+ console.log(nestedObject.getter('a.b','c',['d','j'])); // -> null
235
+ // -> test code getter by type Instance.
139
- nestedPropIns.setter('mem1.mem2.mem3.mem4.mem6', '12346');
236
+ console.log(nestedPropIns.getter('mem1.mem2.mem3.mem4.mem5')); // -> 12345
140
- console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: '12345', mem6: '12346'}}}}};
237
+ console.log(nestedPropIns.getter('mem1.mem2.mem3.mem5.mem5')); // -> null
141
-
238
+ })();
142
239
  ```

1

最終コードを投稿

2020/10/12 02:50

投稿

tama_yn0815
tama_yn0815

スコア143

title CHANGED
File without changes
body CHANGED
@@ -58,4 +58,85 @@
58
58
  return _obj;
59
59
  };
60
60
  })()
61
+ ```
62
+
63
+ ### 最終的に出来上がったソースコード
64
+ ```javascriot
65
+ Object.prototype.setter = function(member, /*...multilayered, */value) {// -> member, multilayered, vは実質使用しない....残余引数で対応したい
66
+ var _obj = this;// -> Class化されたオブジェクトに対応
67
+ // 通常配列化
68
+ var _args = Array.from(arguments); // -> ポリフィルを作成した(IEとか対応)
69
+ if (_args.length < 2) {
70
+ var msg = 'Unexpected execution: there are not enough arguments to execute ' + typeof this + '.';
71
+ throw new UserException(msg, 'error'); // -> typeは列挙型にしたい
72
+ }
73
+ var changeAssignValue = _args.pop(); // -> _argsから最後の要素を削除し、変数[changeAssignValue]でキャッチする
74
+ var menberKeyList = getMenberKeyList(_args.flat(1/0)); //-> _argsの中身を単配列化&階層を配列に詰める
75
+ var menberLayeredLength = menberKeyList.length;
76
+ var menberListIndex = 0;
77
+ var hasMenber = false;
78
+ var memberName = void(0);
79
+ var o = _obj; // -> 処理用変数
80
+ var isLast = false;
81
+ while (menberListIndex < menberLayeredLength) {
82
+ isLast = (menberListIndex == menberLayeredLength - 1);
83
+ memberName = menberKeyList[menberListIndex];
84
+ hasMenber = o.hasOwnProperty(memberName); // -> _objではダメ。。1階層目以外書き換え不可
85
+ if (hasMenber) {
86
+ // 最後のindexのみ、propertyの書き換え
87
+ if (isLast) {
88
+ Object.defineProperty(o, memberName, { value: changeAssignValue, writable: false, enumerable: true });
89
+ }
90
+ } else {
91
+ o[memberName] = {};// -> 不用意なメンバー追加は避けた方が良いかも。。。
92
+ }
93
+ o = o[memberName];
94
+ menberListIndex++;
95
+ }
96
+ return _obj;
97
+ // 階層を順番に並び替えて返却(単配列化)
98
+ function getMenberKeyList (obj) {
99
+ return (!Array.isArray(obj) || obj.length < 1) ? [] : (function (r, o) {
100
+ var i = 0;
101
+ while (i < o.length) {
102
+ var k = o[i];
103
+ if (Array.isArray(k)) { k = k.flat(1/0).join('.'); }
104
+ if (typeof k != 'string') { k = k.toString(); }
105
+ k = k.split('.');
106
+ r = r.concat(k);
107
+ i++;
108
+ }
109
+ return r;
110
+ })([], obj);
111
+ }
112
+ };
113
+
114
+ // -> test code type Array
115
+ var nestedArray = [[[[[[1,2,3]]]]]];
116
+ console.log(nestedArray); // -> [0: [0: [0: [0: [0: [0: 1. 1: 2, 2: 3]]]]]];
117
+ nestedArray.setter('0.0.0.0.0.1',5);
118
+ console.log(nestedArray); // -> [0: [0: [0: [0: [0: [0: 1. 1: 5, 2: 3]]]]]];
119
+
120
+ // -> test code type Object
121
+ var nestedObject = {a: {b: {c: {d: {e: 'hoge', z: 'fuga'}}}}};
122
+ console.log(nestedObject); // -> {a: {b: {c: {d: {e: 'hoge', z: 'fuga'}}}}};
123
+ nestedObject.setter('a.b','c',['d','e'],'hogehoge');
124
+ console.log(nestedObject); // -> {a: {b: {c: {d: {e: 'hogehoge', z: 'fuga'}}}}};
125
+
126
+ // -> test code type Instance
127
+ var _func = function _func () {
128
+ this.mem1 = {};
129
+ this.mem1.mem2 = {};
130
+ this.mem1.mem2.mem3 = {};
131
+ this.mem1.mem2.mem3.mem4 = {};
132
+ this.mem1.mem2.mem3.mem4.mem5 = 'member5';
133
+ this.mem1.mem2.mem3.mem4.mem6 = 'member6';
134
+ }
135
+ var nestedPropIns = new _func();
136
+ console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: 'member5', mem6: 'member6'}}}}};
137
+ nestedPropIns.setter('mem1.mem2.mem3.mem4.mem5', '12345');
138
+ console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: '12345', mem6: 'member6'}}}}};
139
+ nestedPropIns.setter('mem1.mem2.mem3.mem4.mem6', '12346');
140
+ console.log(nestedPropIns); // -> _func: {mem1: {mem2: {mem3: {mem4: {mem5: '12345', mem6: '12346'}}}}};
141
+
61
142
  ```