]> git.proxmox.com Git - pve-eslint.git/blob - eslint/docs/src/rules/no-implicit-globals.md
15c03861d55e1cb245901648ba389aab2d164019
[pve-eslint.git] / eslint / docs / src / rules / no-implicit-globals.md
1 ---
2 title: no-implicit-globals
3 layout: doc
4 rule_type: suggestion
5 related_rules:
6 - no-undef
7 - no-global-assign
8 further_reading:
9 - https://benalman.com/news/2010/11/immediately-invoked-function-expression/
10 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Undeclared_var
11 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone
12 ---
13
14
15 It is the best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script.
16
17 Global variables created from a script can produce name collisions with global variables created from another script, which will
18 usually lead to runtime errors or unexpected behavior.
19
20 This rule disallows the following:
21
22 * Declarations that create one or more variables in the global scope.
23 * Global variable leaks.
24 * Redeclarations of read-only global variables and assignments to read-only global variables.
25
26 There is an explicit way to create a global variable when needed, by assigning to a property of the global object.
27
28 This rule is mostly useful for browser scripts. Top-level declarations in ES modules and CommonJS modules create module-scoped
29 variables. ES modules also have implicit `strict` mode, which prevents global variable leaks.
30
31 By default, this rule does not check `const`, `let` and `class` declarations.
32
33 This rule has an object option with one option:
34
35 * Set `"lexicalBindings"` to `true` if you want this rule to check `const`, `let` and `class` declarations as well.
36
37 ## Rule Details
38
39 ### `var` and `function` declarations
40
41 When working with browser scripts, developers often forget that variable and function declarations at the top-level scope become global variables on the `window` object. As opposed to modules which have their own scope. Globals should be explicitly assigned to `window` or `self` if that is the intent. Otherwise variables intended to be local to the script should be wrapped in an IIFE.
42
43 This rule disallows `var` and `function` declarations at the top-level script scope. This does not apply to ES and CommonJS modules since they have a module scope.
44
45 Examples of **incorrect** code for this rule:
46
47 ::: incorrect
48
49 ```js
50 /*eslint no-implicit-globals: "error"*/
51
52 var foo = 1;
53
54 function bar() {}
55 ```
56
57 :::
58
59 Examples of **correct** code for this rule:
60
61 ::: correct
62
63 ```js
64 /*eslint no-implicit-globals: "error"*/
65
66 // explicitly set on window
67 window.foo = 1;
68 window.bar = function() {};
69
70 // intended to be scope to this file
71 (function() {
72 var foo = 1;
73
74 function bar() {}
75 })();
76 ```
77
78 :::
79
80 Examples of **correct** code for this rule with `"parserOptions": { "sourceType": "module" }` in the ESLint configuration:
81
82 ::: correct
83
84 ```js
85 /*eslint no-implicit-globals: "error"*/
86
87 // foo and bar are local to module
88 var foo = 1;
89 function bar() {}
90 ```
91
92 :::
93
94 ### Global variable leaks
95
96 When the code is not in `strict` mode, an assignment to an undeclared variable creates
97 a new global variable. This will happen even if the code is in a function.
98
99 This does not apply to ES modules since the module code is implicitly in `strict` mode.
100
101 Examples of **incorrect** code for this rule:
102
103 ::: incorrect
104
105 ```js
106 /*eslint no-implicit-globals: "error"*/
107
108 foo = 1;
109
110 Bar.prototype.baz = function () {
111 a = 1; // Intended to be this.a = 1;
112 };
113 ```
114
115 :::
116
117 ### Read-only global variables
118
119 This rule also disallows redeclarations of read-only global variables and assignments to read-only global variables.
120
121 A read-only global variable can be a built-in ES global (e.g. `Array`), an environment specific global
122 (e.g. `window` in the browser environment), or a global variable defined as `readonly` in the configuration file
123 or in a `/*global */` comment.
124
125 * [Specifying Environments](../user-guide/configuring#specifying-environments)
126 * [Specifying Globals](../user-guide/configuring#specifying-globals)
127
128 Examples of **incorrect** code for this rule:
129
130 ::: incorrect
131
132 ```js
133 /*eslint no-implicit-globals: "error"*/
134
135 /*global foo:readonly*/
136
137 foo = 1;
138
139 Array = [];
140 var Object;
141 ```
142
143 :::
144
145 ### `const`, `let` and `class` declarations
146
147 Lexical declarations `const` and `let`, as well as `class` declarations, create variables that are block-scoped.
148
149 However, when declared in the top-level of a browser script these variables are not 'script-scoped'.
150 They are actually created in the global scope and could produce name collisions with
151 `var`, `const` and `let` variables and `function` and `class` declarations from other scripts.
152 This does not apply to ES and CommonJS modules.
153
154 If the variable is intended to be local to the script, wrap the code with a block or with an immediately-invoked function expression (IIFE).
155
156 Examples of **correct** code for this rule with `"lexicalBindings"` option set to `false` (default):
157
158 ::: correct
159
160 ```js
161 /*eslint no-implicit-globals: ["error", {"lexicalBindings": false}]*/
162
163 const foo = 1;
164
165 let baz;
166
167 class Bar {}
168 ```
169
170 :::
171
172 Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`:
173
174 ::: incorrect
175
176 ```js
177 /*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
178
179 const foo = 1;
180
181 let baz;
182
183 class Bar {}
184 ```
185
186 :::
187
188 Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`:
189
190 ::: correct
191
192 ```js
193 /*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
194
195 {
196 const foo = 1;
197 let baz;
198 class Bar {}
199 }
200
201 (function() {
202 const foo = 1;
203 let baz;
204 class Bar {}
205 }());
206 ```
207
208 :::
209
210 If you intend to create a global `const` or `let` variable or a global `class` declaration, to be used from other scripts,
211 be aware that there are certain differences when compared to the traditional methods, which are `var` declarations and assigning to a property of the global `window` object:
212
213 * Lexically declared variables cannot be conditionally created. A script cannot check for the existence of
214 a variable and then create a new one. `var` variables are also always created, but redeclarations do not
215 cause runtime exceptions.
216 * Lexically declared variables do not create properties on the global object, which is what a consuming script might expect.
217 * Lexically declared variables are shadowing properties of the global object, which might produce errors if a
218 consuming script is using both the variable and the property.
219 * Lexically declared variables can produce a permanent Temporal Dead Zone (TDZ) if the initialization throws an exception.
220 Even the `typeof` check is not safe from TDZ reference exceptions.
221
222 Examples of **incorrect** code for this rule with `"lexicalBindings"` option set to `true`:
223
224 ::: incorrect
225
226 ```js
227 /*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
228
229 const MyGlobalFunction = (function() {
230 const a = 1;
231 let b = 2;
232 return function() {
233 return a + b;
234 }
235 }());
236 ```
237
238 :::
239
240 Examples of **correct** code for this rule with `"lexicalBindings"` option set to `true`:
241
242 ::: correct
243
244 ```js
245 /*eslint no-implicit-globals: ["error", {"lexicalBindings": true}]*/
246
247 window.MyGlobalFunction = (function() {
248 const a = 1;
249 let b = 2;
250 return function() {
251 return a + b;
252 }
253 }());
254 ```
255
256 :::
257
258 ## When Not To Use It
259
260 In the case of a browser script, if you want to be able to explicitly declare variables and functions in the global scope,
261 and your code is in strict mode or you don't want this rule to warn you about undeclared variables,
262 and you also don't want this rule to warn you about read-only globals, you can disable this rule.
263
264 In the case of a CommonJS module, if your code is in strict mode or you don't want this rule to warn you about undeclared variables,
265 and you also don't want this rule to warn you about the read-only globals, you can disable this rule.
266
267 In the case of an ES module, if you don't want this rule to warn you about the read-only globals you can disable this rule.