]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | # Suggest using Reflect methods where applicable (prefer-reflect) |
2 | ||
3 | This rule was **deprecated** in ESLint v3.9.0 and will not be replaced. The original intent of this rule now seems misguided as we have come to understand that `Reflect` methods are not actually intended to replace the `Object` counterparts the rule suggests, but rather exist as low-level primitives to be used with proxies in order to replicate the default behavior of various previously existing functionality. | |
4 | ||
5 | The ES6 Reflect API comes with a handful of methods which somewhat deprecate methods on old constructors: | |
6 | ||
7 | * [`Reflect.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.apply) effectively deprecates [`Function.prototype.apply`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.apply) and [`Function.prototype.call`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-function.prototype.call) | |
8 | * [`Reflect.deleteProperty`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.deleteproperty) effectively deprecates the [`delete` keyword](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-delete-operator-runtime-semantics-evaluation) | |
9 | * [`Reflect.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getownpropertydescriptor) effectively deprecates [`Object.getOwnPropertyDescriptor`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getownpropertydescriptor) | |
10 | * [`Reflect.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.getprototypeof) effectively deprecates [`Object.getPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.getprototypeof) | |
11 | * [`Reflect.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.setprototypeof) effectively deprecates [`Object.setPrototypeOf`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof) | |
12 | * [`Reflect.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-reflect.preventextensions) effectively deprecates [`Object.preventExtensions`](https://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.preventextensions) | |
13 | ||
14 | The prefer-reflect rule will flag usage of any older method, suggesting to instead use the newer Reflect version. | |
15 | ||
16 | ## Rule Details | |
17 | ||
18 | ## Options | |
19 | ||
20 | ### Exceptions | |
21 | ||
34eeec05 | 22 | ```js |
eb39fafa DC |
23 | "prefer-reflect": [<enabled>, { "exceptions": [<...exceptions>] }] |
24 | ``` | |
25 | ||
26 | The `exceptions` option allows you to pass an array of methods names you'd like to continue to use in the old style. | |
27 | ||
28 | For example if you wish to use all Reflect methods, except for `Function.prototype.apply` then your config would look like `prefer-reflect: [2, { "exceptions": ["apply"] }]`. | |
29 | ||
30 | If you want to use Reflect methods, but keep using the `delete` keyword, then your config would look like `prefer-reflect: [2, { "exceptions": ["delete"] }]`. | |
31 | ||
32 | These can be combined as much as you like. To make all methods exceptions (thereby rendering this rule useless), use `prefer-reflect: [2, { "exceptions": ["apply", "call", "defineProperty", "getOwnPropertyDescriptor", "getPrototypeOf", "setPrototypeOf", "isExtensible", "getOwnPropertyNames", "preventExtensions", "delete"] }]` | |
33 | ||
34 | ### Reflect.apply | |
35 | ||
36 | Deprecates `Function.prototype.apply()` and `Function.prototype.call()` | |
37 | ||
38 | Examples of **incorrect** code for this rule when used without exceptions: | |
39 | ||
40 | ```js | |
41 | /*eslint prefer-reflect: "error"*/ | |
42 | ||
43 | myFunction.apply(undefined, args); | |
44 | myFunction.apply(null, args); | |
45 | obj.myMethod.apply(obj, args); | |
46 | obj.myMethod.apply(other, args); | |
47 | ||
48 | myFunction.call(undefined, arg); | |
49 | myFunction.call(null, arg); | |
50 | obj.myMethod.call(obj, arg); | |
51 | obj.myMethod.call(other, arg); | |
52 | ``` | |
53 | ||
54 | Examples of **correct** code for this rule when used without exceptions: | |
55 | ||
56 | ```js | |
57 | /*eslint prefer-reflect: "error"*/ | |
58 | ||
59 | Reflect.apply(myFunction, undefined, args); | |
60 | Reflect.apply(myFunction, null, args); | |
61 | Reflect.apply(obj.myMethod, obj, args); | |
62 | Reflect.apply(obj.myMethod, other, args); | |
63 | Reflect.apply(myFunction, undefined, [arg]); | |
64 | Reflect.apply(myFunction, null, [arg]); | |
65 | Reflect.apply(obj.myMethod, obj, [arg]); | |
66 | Reflect.apply(obj.myMethod, other, [arg]); | |
67 | ``` | |
68 | ||
69 | Examples of **correct** code for this rule with the `{ "exceptions": ["apply"] }` option: | |
70 | ||
71 | ```js | |
72 | /*eslint prefer-reflect: ["error", { "exceptions": ["apply"] }]*/ | |
73 | ||
74 | // in addition to Reflect.apply(...): | |
75 | myFunction.apply(undefined, args); | |
76 | myFunction.apply(null, args); | |
77 | obj.myMethod.apply(obj, args); | |
78 | obj.myMethod.apply(other, args); | |
79 | ``` | |
80 | ||
81 | Examples of **correct** code for this rule with the `{ "exceptions": ["call"] }` option: | |
82 | ||
83 | ```js | |
84 | /*eslint prefer-reflect: ["error", { "exceptions": ["call"] }]*/ | |
85 | ||
86 | // in addition to Reflect.apply(...): | |
87 | myFunction.call(undefined, arg); | |
88 | myFunction.call(null, arg); | |
89 | obj.myMethod.call(obj, arg); | |
90 | obj.myMethod.call(other, arg); | |
91 | ``` | |
92 | ||
93 | ### Reflect.defineProperty | |
94 | ||
95 | Deprecates `Object.defineProperty()` | |
96 | ||
97 | Examples of **incorrect** code for this rule when used without exceptions: | |
98 | ||
99 | ```js | |
100 | /*eslint prefer-reflect: "error"*/ | |
101 | ||
102 | Object.defineProperty({}, 'foo', {value: 1}) | |
103 | ``` | |
104 | ||
105 | Examples of **correct** code for this rule when used without exceptions: | |
106 | ||
107 | ```js | |
108 | /*eslint prefer-reflect: "error"*/ | |
109 | ||
110 | Reflect.defineProperty({}, 'foo', {value: 1}) | |
111 | ``` | |
112 | ||
113 | Examples of **correct** code for this rule with the `{ "exceptions": ["defineProperty"] }` option: | |
114 | ||
115 | ```js | |
116 | /*eslint prefer-reflect: ["error", { "exceptions": ["defineProperty"] }]*/ | |
117 | ||
118 | Object.defineProperty({}, 'foo', {value: 1}) | |
119 | Reflect.defineProperty({}, 'foo', {value: 1}) | |
120 | ``` | |
121 | ||
122 | ### Reflect.getOwnPropertyDescriptor | |
123 | ||
124 | Deprecates `Object.getOwnPropertyDescriptor()` | |
125 | ||
126 | Examples of **incorrect** code for this rule when used without exceptions: | |
127 | ||
128 | ```js | |
129 | /*eslint prefer-reflect: "error"*/ | |
130 | ||
131 | Object.getOwnPropertyDescriptor({}, 'foo') | |
132 | ``` | |
133 | ||
134 | Examples of **correct** code for this rule when used without exceptions: | |
135 | ||
136 | ```js | |
137 | /*eslint prefer-reflect: "error"*/ | |
138 | ||
139 | Reflect.getOwnPropertyDescriptor({}, 'foo') | |
140 | ``` | |
141 | ||
142 | Examples of **correct** code for this rule with the `{ "exceptions": ["getOwnPropertyDescriptor"] }` option: | |
143 | ||
144 | ```js | |
145 | /*eslint prefer-reflect: ["error", { "exceptions": ["getOwnPropertyDescriptor"] }]*/ | |
146 | ||
147 | Object.getOwnPropertyDescriptor({}, 'foo') | |
148 | Reflect.getOwnPropertyDescriptor({}, 'foo') | |
149 | ``` | |
150 | ||
151 | ### Reflect.getPrototypeOf | |
152 | ||
153 | Deprecates `Object.getPrototypeOf()` | |
154 | ||
155 | Examples of **incorrect** code for this rule when used without exceptions: | |
156 | ||
157 | ```js | |
158 | /*eslint prefer-reflect: "error"*/ | |
159 | ||
160 | Object.getPrototypeOf({}, 'foo') | |
161 | ``` | |
162 | ||
163 | Examples of **correct** code for this rule when used without exceptions: | |
164 | ||
165 | ```js | |
166 | /*eslint prefer-reflect: "error"*/ | |
167 | ||
168 | Reflect.getPrototypeOf({}, 'foo') | |
169 | ``` | |
170 | ||
171 | Examples of **correct** code for this rule with the `{ "exceptions": ["getPrototypeOf"] }` option: | |
172 | ||
173 | ```js | |
174 | /*eslint prefer-reflect: ["error", { "exceptions": ["getPrototypeOf"] }]*/ | |
175 | ||
176 | Object.getPrototypeOf({}, 'foo') | |
177 | Reflect.getPrototypeOf({}, 'foo') | |
178 | ``` | |
179 | ||
180 | ### Reflect.setPrototypeOf | |
181 | ||
182 | Deprecates `Object.setPrototypeOf()` | |
183 | ||
184 | Examples of **incorrect** code for this rule when used without exceptions: | |
185 | ||
186 | ```js | |
187 | /*eslint prefer-reflect: "error"*/ | |
188 | ||
189 | Object.setPrototypeOf({}, Object.prototype) | |
190 | ``` | |
191 | ||
192 | Examples of **correct** code for this rule when used without exceptions: | |
193 | ||
194 | ```js | |
195 | /*eslint prefer-reflect: "error"*/ | |
196 | ||
197 | Reflect.setPrototypeOf({}, Object.prototype) | |
198 | ``` | |
199 | ||
200 | Examples of **correct** code for this rule with the `{ "exceptions": ["setPrototypeOf"] }` option: | |
201 | ||
202 | ```js | |
203 | /*eslint prefer-reflect: ["error", { "exceptions": ["setPrototypeOf"] }]*/ | |
204 | ||
205 | Object.setPrototypeOf({}, Object.prototype) | |
206 | Reflect.setPrototypeOf({}, Object.prototype) | |
207 | ``` | |
208 | ||
209 | ### Reflect.isExtensible | |
210 | ||
211 | Deprecates `Object.isExtensible` | |
212 | ||
213 | Examples of **incorrect** code for this rule when used without exceptions: | |
214 | ||
215 | ```js | |
216 | /*eslint prefer-reflect: "error"*/ | |
217 | ||
218 | Object.isExtensible({}) | |
219 | ``` | |
220 | ||
221 | Examples of **correct** code for this rule when used without exceptions: | |
222 | ||
223 | ```js | |
224 | /*eslint prefer-reflect: "error"*/ | |
225 | ||
226 | Reflect.isExtensible({}) | |
227 | ``` | |
228 | ||
229 | Examples of **correct** code for this rule with the `{ "exceptions": ["isExtensible"] }` option: | |
230 | ||
231 | ```js | |
232 | /*eslint prefer-reflect: ["error", { "exceptions": ["isExtensible"] }]*/ | |
233 | ||
234 | Object.isExtensible({}) | |
235 | Reflect.isExtensible({}) | |
236 | ``` | |
237 | ||
238 | ### Reflect.getOwnPropertyNames | |
239 | ||
240 | Deprecates `Object.getOwnPropertyNames()` | |
241 | ||
242 | Examples of **incorrect** code for this rule when used without exceptions: | |
243 | ||
244 | ```js | |
245 | /*eslint prefer-reflect: "error"*/ | |
246 | ||
247 | Object.getOwnPropertyNames({}) | |
248 | ``` | |
249 | ||
250 | Examples of **correct** code for this rule when used without exceptions: | |
251 | ||
252 | ```js | |
253 | /*eslint prefer-reflect: "error"*/ | |
254 | ||
255 | Reflect.getOwnPropertyNames({}) | |
256 | ``` | |
257 | ||
258 | Examples of **correct** code for this rule with the `{ "exceptions": ["getOwnPropertyNames"] }` option: | |
259 | ||
260 | ```js | |
261 | /*eslint prefer-reflect: ["error", { "exceptions": ["getOwnPropertyNames"] }]*/ | |
262 | ||
263 | Object.getOwnPropertyNames({}) | |
264 | Reflect.getOwnPropertyNames({}) | |
265 | ``` | |
266 | ||
267 | ### Reflect.preventExtensions | |
268 | ||
269 | Deprecates `Object.preventExtensions()` | |
270 | ||
271 | Examples of **incorrect** code for this rule when used without exceptions: | |
272 | ||
273 | ```js | |
274 | /*eslint prefer-reflect: "error"*/ | |
275 | ||
276 | Object.preventExtensions({}) | |
277 | ``` | |
278 | ||
279 | Examples of **correct** code for this rule when used without exceptions: | |
280 | ||
281 | ```js | |
282 | /*eslint prefer-reflect: "error"*/ | |
283 | ||
284 | Reflect.preventExtensions({}) | |
285 | ``` | |
286 | ||
287 | Examples of **correct** code for this rule with the `{ "exceptions": ["preventExtensions"] }` option: | |
288 | ||
289 | ```js | |
290 | /*eslint prefer-reflect: ["error", { "exceptions": ["preventExtensions"] }]*/ | |
291 | ||
292 | Object.preventExtensions({}) | |
293 | Reflect.preventExtensions({}) | |
294 | ``` | |
295 | ||
296 | ### Reflect.deleteProperty | |
297 | ||
298 | Deprecates the `delete` keyword | |
299 | ||
300 | Examples of **incorrect** code for this rule when used without exceptions: | |
301 | ||
302 | ```js | |
303 | /*eslint prefer-reflect: "error"*/ | |
304 | ||
305 | delete foo.bar; // deleting object property | |
306 | ``` | |
307 | ||
308 | Examples of **correct** code for this rule when used without exceptions: | |
309 | ||
310 | ```js | |
311 | /*eslint prefer-reflect: "error"*/ | |
312 | ||
313 | delete bar; // deleting variable | |
314 | Reflect.deleteProperty(foo, 'bar'); | |
315 | ``` | |
316 | ||
317 | Note: For a rule preventing deletion of variables, see [no-delete-var instead](no-delete-var.md) | |
318 | ||
319 | Examples of **correct** code for this rule with the `{ "exceptions": ["delete"] }` option: | |
320 | ||
321 | ```js | |
322 | /*eslint prefer-reflect: ["error", { "exceptions": ["delete"] }]*/ | |
323 | ||
324 | delete bar | |
325 | delete foo.bar | |
326 | Reflect.deleteProperty(foo, 'bar'); | |
327 | ``` | |
328 | ||
329 | ## When Not To Use It | |
330 | ||
331 | This rule should not be used in ES3/5 environments. | |
332 | ||
333 | In ES2015 (ES6) or later, if you don't want to be notified about places where Reflect could be used, you can safely disable this rule. | |
334 | ||
335 | ## Related Rules | |
336 | ||
337 | * [no-useless-call](no-useless-call.md) | |
338 | * [prefer-spread](prefer-spread.md) | |
339 | * [no-delete-var](no-delete-var.md) |