Skip to content

Commit f99574f

Browse files
committed
up
1 parent 3defacc commit f99574f

File tree

178 files changed

+530
-271
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

178 files changed

+530
-271
lines changed

1-js/7-advanced-syntax/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# More syntax
1+
# More syntax [todo move error handling]
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
2+
3+
# Global object
4+
5+
When Javascript was created, there was an idea of a "global object" that provides all global variables and functions. It was planned that multiple in-browser scripts would use that single global object and share variables through it.
6+
7+
Since then, Javascript greatly evolved, and that idea of linking code through global variables became much less appealing. In modern Javascript, the concept of modules too its place.
8+
9+
But the global object still remains in the specification.
10+
11+
In a browser it is named "window", for Node.JS it is "global", for other environments it may have another name.
12+
13+
It does two things:
14+
15+
1. Provides access to built-in functions and values, defined by the specification and the environment.
16+
For instance, we can call `alert` directly or as a method of `window`:
17+
18+
```js run
19+
alert("Hello");
20+
21+
// the same as
22+
window.alert("Hello");
23+
```
24+
25+
The same applies to other built-ins. E.g. we can use `window.Array` instead of `Array`.
26+
27+
2. Provides access to global Function Declarations and `var` variables. We can read them and write using its properties, for instance:
28+
29+
<!-- no-strict to move variables out of eval -->
30+
```js untrusted run no-strict refresh
31+
var phrase = "Hello";
32+
33+
function sayHi() {
34+
alert(phrase);
35+
}
36+
37+
// can read from window
38+
alert( window.phrase ); // Hello (global var)
39+
alert( window.sayHi ); // function (global function declaration)
40+
41+
// can write to window (creates a new sglobal variable)
42+
window.test = 5;
43+
44+
alert(test); // 5
45+
```
46+
47+
...But the global object does not have variables declared with `let/const`!
48+
49+
```js untrusted run no-strict refresh
50+
*!*let*/!* user = "John";
51+
alert(user); // John
52+
53+
alert(window.user); // undefined, don't have let
54+
alert("user" in window); // false
55+
```
56+
57+
```smart header="The global object is not a global Environment Record"
58+
In versions of ECMAScript prior to ES-2015, there were no `let/const` variables, only `var`. And global object was used as a global Environment Record (wordings were a bit different, but that's the gist).
59+
60+
But starting from ES-2015, these entities are split apart. There's a global Lexical Environment with its Environment Record. And there's a global object that provides *some* of global variables.
61+
62+
As a practical difference, global `let/const` variables are definitively properties of the global Environment Record, but they do not exist in the global object.
63+
64+
Naturally, that's because the idea of a global object as a way to access "all global things" comes from ancient times. Nowadays is not considered to be a good thing. Modern language features like `let/const` do not make friends with it, but old ones are still compatible.
65+
```
66+
67+
## Uses of "window"
68+
69+
In server-side environments like Node.JS, the `global` object is used exceptionally rarely. Probably it would be fair to say "never".
70+
71+
In-browser `window` is sometimes used though.
72+
73+
Usually, it's not a good idea to use it, but here are some examples you can meet.
74+
75+
1. To access exactly the global variable if the function has the local one with the same name.
76+
77+
```js untrusted run no-strict refresh
78+
var user = "Global";
79+
80+
function sayHi() {
81+
var user = "Local";
82+
83+
*!*
84+
alert(window.user); // Global
85+
*/!*
86+
}
87+
88+
sayHi();
89+
```
90+
91+
Such use is a workaround. Would be better to name variables differently, that won't require use to write the code it this way. And please note `"var"` before `user`. The trick doesn't work with `let` variables.
92+
93+
2. To check if a certain global variable or a builtin exists.
94+
95+
For instance, we want to check whether a global function `XMLHttpRequest` exists.
96+
97+
We can't write `if (XMLHttpRequest)`, because if there's no `XMLHttpRequest`, there will be an error (variable not defined).
98+
99+
But we can read it from `window.XMLHttpRequest`:
100+
101+
```js run
102+
if (window.XMLHttpRequest) {
103+
alert('XMLHttpRequest exists!')
104+
}
105+
```
106+
107+
If there is no such global function then `window.XMLHttpRequest` is just a non-existing object property. That's `undefined`, no error, so it works.
108+
109+
We can also write the test without `window`:
110+
111+
```js
112+
if (typeof XMLHttpRequest == 'function') {
113+
/* is there a function XMLHttpRequest? */
114+
}
115+
```
116+
117+
This doesn't use `window`, but is (theoretically) less reliable, because `typeof` may use a local XMLHttpRequest, and we want the global one.
118+
119+
120+
3. To take the variable from the right window. That's probably the most valid use case.
121+
122+
A browser may open multiple windows and tabs. A window may also embed another one in `<iframe>`. Every browser window has its own `window` object and global variables. Javascript allows windows that come from the same site (same protocol, host, port) to access variables from each other.
123+
124+
That use is a little bit beyound our scope for now, but it looks like:
125+
```html run
126+
<iframe src="/" id="iframe"></iframe>
127+
128+
<script>
129+
alert( innerWidth ); // get innerWidth property of the current window (browser only)
130+
alert( Array ); // get Array of the current window (javascript core builtin)
131+
132+
// when the iframe loads...
133+
iframe.onload = function() {
134+
// get width of the iframe window
135+
*!*
136+
alert( iframe.contentWindow.innerWidth );
137+
*/!*
138+
// get the builtin Array from the iframe window
139+
*!*
140+
alert( iframe.contentWindow.Array );
141+
*/!*
142+
};
143+
</script>
144+
```
145+
146+
Here, first two alerts use the current window, and the latter two take variables from `iframe` window. Can be any variables if `iframe` originates from the same protocol/host/port.
147+
148+
## "this" and global object
149+
150+
Sometimes, the value of `this` is exactly the global object. That's rarely used, but some scripts rely on that.
151+
152+
1. In the browser, the value of `this` in the global area is `window`:
153+
154+
```js run
155+
// outside of functions
156+
alert( this === window ); // true
157+
```
158+
159+
Other, non-browser environments, may use another value for `this` in such cases.
160+
161+
2. When a function with `this` is called in not-strict mode, it gets the global object as `this`:
162+
```js run no-strict
163+
// not in strict mode (!)
164+
function f() {
165+
alert(this); // [object Window]
166+
}
167+
168+
f(); // called without an object
169+
```
170+
171+
By specification, `this` in this case must be the global object, even in non-browser environments like Node.JS. That's for compatibility with old scripts, in strict mode `this` would be `undefined`.

1-js/8-more-functions/04-function-object/2-counter-inc-dec/_js.view/solution.js renamed to 1-js/8-more-functions/05-function-object/2-counter-inc-dec/_js.view/solution.js

File renamed without changes.

1-js/8-more-functions/04-function-object/2-counter-inc-dec/_js.view/source.js renamed to 1-js/8-more-functions/05-function-object/2-counter-inc-dec/_js.view/source.js

File renamed without changes.

1-js/8-more-functions/04-function-object/2-counter-inc-dec/_js.view/test.js renamed to 1-js/8-more-functions/05-function-object/2-counter-inc-dec/_js.view/test.js

File renamed without changes.

1-js/8-more-functions/04-function-object/2-counter-inc-dec/solution.md renamed to 1-js/8-more-functions/05-function-object/2-counter-inc-dec/solution.md

File renamed without changes.

1-js/8-more-functions/04-function-object/2-counter-inc-dec/task.md renamed to 1-js/8-more-functions/05-function-object/2-counter-inc-dec/task.md

File renamed without changes.

1-js/8-more-functions/04-function-object/5-sum-many-brackets/solution.md renamed to 1-js/8-more-functions/05-function-object/5-sum-many-brackets/solution.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11

22
1. For the whole thing to work *anyhow*, the result of `sum` must be function.
33
2. That function must keep in memory the current value between calls.
4-
3. According to the task, the function must become the number when used in `==`. Functions are objects, so the conversion happens as described in the chapter <info:object-toprimitive>, and we can provide our own method that returns the number.
4+
3. According to the task, the function must become the number when used in `==`. Functions are objects, so the conversion happens as described in the chapter <info:object-toprimitive>, and we can provide our own method that returns the number.
55

66
Now the code:
77

88
```js run
99
function sum(a) {
1010

11-
var currentSum = a;
11+
let currentSum = a;
1212

1313
function f(b) {
1414
currentSum += b;
@@ -53,4 +53,3 @@ function f(b) {
5353
```
5454

5555
This `f` will be used in the next call, again return itself, so many times as needed. Then, when used as a number or a string -- the `toString` returns the `currentSum`. We could also use `Symbol.toPrimitive` or `valueOf` here for the conversion.
56-

1-js/8-more-functions/04-function-object/5-sum-many-brackets/task.md renamed to 1-js/8-more-functions/05-function-object/5-sum-many-brackets/task.md

File renamed without changes.

0 commit comments

Comments
 (0)