You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/05-data-types/01-primitives-methods/1-string-new-property/solution.md
+7-14Lines changed: 7 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,26 +6,19 @@ let str = "Hello";
6
6
7
7
str.test=5; // (*)
8
8
9
-
alert(str.test);
9
+
alert(str.test);
10
10
```
11
11
12
-
There may be two kinds of result:
13
-
1.`undefined`
14
-
2. An error.
12
+
Depending on whether you have `use strict` or not, the result may be:
13
+
1.`undefined` (no strict mode)
14
+
2. An error (strict mode).
15
15
16
16
Why? Let's replay what's happening at line `(*)`:
17
17
18
18
1. When a property of `str` is accessed, a "wrapper object" is created.
19
-
2. The operation with the property is carried out on it. So, the object gets the `test` property.
20
-
3. The operation finishes and the "wrapper object" disappears.
21
-
22
-
So, on the last line, `str` has no trace of the property. A new wrapper object for every object operation on a string.
23
-
24
-
Some browsers though may decide to further limit the programmer and disallow to assign properties to primitives at all. That's why in practice we can also see errors at line `(*)`. It's a little bit farther from the specification though.
19
+
2. In strict mode, writing into it is an error.
20
+
3. Otherwise, the operation with the property is carried on, the object gets the `test` property, but after that the "wrapper object" disappears, so in the last line `str` has no trace of the property.
25
21
26
22
**This example clearly shows that primitives are not objects.**
27
23
28
-
They just can not store data.
29
-
30
-
All property/method operations are performed with the help of temporary objects.
Copy file name to clipboardExpand all lines: 1-js/05-data-types/01-primitives-methods/article.md
+11-13Lines changed: 11 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,18 @@
1
1
# Methods of primitives
2
2
3
-
JavaScript allows us to work with primitives (strings, numbers, etc.) as if they were objects.
4
-
5
-
They also provide methods to call as such. We will study those soon, but first we'll see how it works because, of course, primitives are not objects (and here we will make it even clearer).
3
+
JavaScript allows us to work with primitives (strings, numbers, etc.) as if they were objects. They also provide methods to call as such. We will study those soon, but first we'll see how it works because, of course, primitives are not objects (and here we will make it even clearer).
6
4
7
5
Let's look at the key distinctions between primitives and objects.
8
6
9
7
A primitive
10
8
11
9
- Is a value of a primitive type.
12
-
- There are 6 primitive types: `string`, `number`, `boolean`, `symbol`, `null` and `undefined`.
10
+
- There are 7 primitive types: `string`, `number`, `bigint`, `boolean`, `symbol`, `null` and `undefined`.
13
11
14
12
An object
15
13
16
14
- Is capable of storing multiple values as properties.
17
-
- Can be created with `{}`, for instance: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript; functions, for example, are objects.
15
+
- Can be created with `{}`, for instance: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript: functions, for example, are objects.
18
16
19
17
One of the best things about objects is that we can store a function as one of its properties.
20
18
@@ -35,7 +33,7 @@ Many built-in objects already exist, such as those that work with dates, errors,
35
33
36
34
But, these features come with a cost!
37
35
38
-
Objects are "heavier" than primitives. They require additional resources to support the internal machinery. But as properties and methods are very useful in programming, JavaScript engines try to optimize them to reduce the additional burden.
36
+
Objects are "heavier" than primitives. They require additional resources to support the internal machinery.
39
37
40
38
## A primitive as an object
41
39
@@ -48,11 +46,11 @@ The solution looks a little bit awkward, but here it is:
48
46
49
47
1. Primitives are still primitive. A single value, as desired.
50
48
2. The language allows access to methods and properties of strings, numbers, booleans and symbols.
51
-
3.When this happens, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.
49
+
3.In order for that to work, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.
52
50
53
51
The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean` and `Symbol`. Thus, they provide different sets of methods.
54
52
55
-
For instance, there exists a method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized string.
53
+
For instance, there exists a string method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized `str`.
56
54
57
55
Here's how it works:
58
56
@@ -84,25 +82,25 @@ We'll see more specific methods in chapters <info:number> and <info:string>.
84
82
85
83
86
84
````warn header="Constructors `String/Number/Boolean` are for internal use only"
87
-
Some languages like Java allow us to create "wrapper objects" for primitives explicitly using a syntax like `new Number(1)` or `new Boolean(false)`.
85
+
Some languages like Java allow us to explicitly create "wrapper objects" for primitives using a syntax like `new Number(1)` or `new Boolean(false)`.
88
86
89
87
In JavaScript, that's also possible for historical reasons, but highly **unrecommended**. Things will go crazy in several places.
90
88
91
89
For instance:
92
90
93
91
```js run
94
-
alert( typeof1 ); // "number"
92
+
alert( typeof0 ); // "number"
95
93
96
-
alert( typeofnewNumber(1) ); // "object"!
94
+
alert( typeofnewNumber(0) ); // "object"!
97
95
```
98
96
99
-
And because what follows, `zero`, is an object, the alert will show up:
97
+
Objects are always truthy in `if`, so here the alert will show up:
100
98
101
99
```js run
102
100
let zero =newNumber(0);
103
101
104
102
if (zero) { // zero is true, because it's an object
Copy file name to clipboardExpand all lines: 1-js/05-data-types/02-number/article.md
+20-19Lines changed: 20 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,12 @@
1
1
# Numbers
2
2
3
-
All numbers in JavaScriptare stored in 64-bit format [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), also known as "double precision".
3
+
In modern JavaScript, there are two types of numbers:
4
4
5
-
Let's recap and expand upon what we currently know about them.
5
+
1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
6
+
7
+
2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed <code>2<sup>53</sup></code> or be less than <code>-2<sup>53</sup></code>. As bigints are used in few special areas, we devote them a special chapter <info:bigint>.
8
+
9
+
So here we'll talk about regular numbers. Let's expand our knowledge of them.
6
10
7
11
## More ways to write a number
8
12
@@ -12,7 +16,7 @@ Imagine we need to write 1 billion. The obvious way is:
12
16
let billion =1000000000;
13
17
```
14
18
15
-
But in real life we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
19
+
But in real life, we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
16
20
17
21
In JavaScript, we shorten a number by appending the letter `"e"` to the number and specifying the zeroes count:
18
22
@@ -29,14 +33,13 @@ In other words, `"e"` multiplies the number by `1` with the given zeroes count.
29
33
1.23e6=1.23*1000000
30
34
```
31
35
32
-
33
36
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
34
37
35
38
```js
36
39
let ms =0.000001;
37
40
```
38
41
39
-
Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say:
42
+
Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say the same as:
40
43
41
44
```js
42
45
let ms =1e-6; // six zeroes to the left from 1
@@ -177,7 +180,7 @@ There are two ways to do so:
177
180
178
181
## Imprecise calculations
179
182
180
-
Internally, a number is represented in 64-bit format [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
183
+
Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
181
184
182
185
If a number is too big, it would overflow the 64-bit storage, potentially giving an infinity:
183
186
@@ -201,19 +204,19 @@ Strange! What is it then if not `0.3`?
201
204
alert( 0.1 + 0.2 ); // 0.30000000000000004
202
205
```
203
206
204
-
Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their chart. The order total will be `$0.30000000000000004`. That would surprise anyone.
207
+
Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
205
208
206
209
But why does this happen?
207
210
208
-
A number is stored in memory in its binary form, a sequence of ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
211
+
A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
209
212
210
213
In other words, what is `0.1`? It is one divided by ten `1/10`, one-tenth. In decimal numeral system such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
211
214
212
215
So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction.
213
216
214
217
There's just no way to store *exactly 0.1* or *exactly 0.2* using the binary system, just like there is no way to store one-third as a decimal fraction.
215
218
216
-
The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", so the number shows up as `0.3`. But beware, the loss still exists.
219
+
The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", but it exists.
217
220
218
221
We can see this in action:
219
222
```js run
@@ -271,13 +274,11 @@ JavaScript doesn't trigger an error in such events. It does its best to fit the
271
274
```smart header="Two zeroes"
272
275
Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`.
273
276
274
-
That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero.
277
+
That's because a sign is represented by a single bit, so it can be set or not set for any number including a zero.
275
278
276
279
In most cases the distinction is unnoticeable, because operators are suited to treat them as the same.
277
280
```
278
281
279
-
280
-
281
282
## Tests: isFinite and isNaN
282
283
283
284
Remember these two special numeric values?
@@ -323,10 +324,10 @@ Please note that an empty or a space-only string is treated as `0` in all numeri
323
324
324
325
```smart header="Compare with `Object.is`"
325
326
326
-
There is a special built-in method [Object.is](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases:
327
+
There is a special built-in method [`Object.is`](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases:
327
328
328
329
1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
329
-
2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, it rarely matters, but these values technically are different.
330
+
2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's true, because internally the number has a sign bit that may be different even if all other bits are zeroes.
330
331
331
332
In all other cases, `Object.is(a, b)` is the same as `a === b`.
332
333
@@ -409,15 +410,15 @@ There are more functions and constants in `Math` object, including trigonometry,
409
410
410
411
## Summary
411
412
412
-
To write big numbers:
413
+
To write numbers with many zeroes:
413
414
414
-
- Append `"e"` with the zeroes count to the number. Like: `123e6` is `123` with 6 zeroes.
415
-
- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. That's for one-millionth or such.
415
+
- Append `"e"` with the zeroes count to the number. Like: `123e6` is the same as `123` with 6 zeroes `123000000`.
416
+
- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. E.g. `123e-6` means `0.000123` (`123` millionths).
416
417
417
418
For different numeral systems:
418
419
419
-
- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems
420
-
- `parseInt(str, base)` parses an integer from any numeral system with base: `2 ≤ base ≤ 36`.
420
+
- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems.
421
+
- `parseInt(str, base)` parses the string `str` into an integer in numeral system with given `base`, `2 ≤ base ≤ 36`.
421
422
- `num.toString(base)` converts a number to a string in the numeral system with the given `base`.
422
423
423
424
For converting values like `12pt` and `100px` to a number:
Copy file name to clipboardExpand all lines: 1-js/05-data-types/03-string/1-ucfirst/solution.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ But we can make a new string based on the existing one, with the uppercased firs
6
6
let newStr = str[0].toUpperCase() +str.slice(1);
7
7
```
8
8
9
-
There's a small problem though. If `str` is empty, then `str[0]` is undefined, so we'll get an error.
9
+
There's a small problem though. If `str` is empty, then `str[0]` is `undefined`, and as `undefined` doesn't have the `toUpperCase()` method, we'll get an error.
0 commit comments