Skip to content

Commit 566b67d

Browse files
committed
update content form upstream
1 parent 6cf54b5 commit 566b67d

File tree

93 files changed

+2138
-1747
lines changed

Some content is hidden

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

93 files changed

+2138
-1747
lines changed

1-js/99-js-misc/05-bigint/article.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# BigInt
2+
3+
[recent caniuse="bigint"]
4+
5+
`BigInt` is a special numeric type that provides support for integers of arbitrary length.
6+
7+
A bigint is created by appending `n` to the end of an integer literal or by calling the function `BigInt` that creates bigints from strings, numbers etc.
8+
9+
```js
10+
const bigint = 1234567890123456789012345678901234567890n;
11+
12+
const sameBigint = BigInt("1234567890123456789012345678901234567890");
13+
14+
const bigintFromNumber = BigInt(10); // same as 10n
15+
```
16+
17+
## Math operators
18+
19+
`BigInt` can mostly be used like a regular number, for example:
20+
21+
```js run
22+
alert(1n + 2n); // 3
23+
24+
alert(5n / 2n); // 2
25+
```
26+
27+
Please note: the division `5/2` returns the result rounded towards zero, without the decimal part. All operations on bigints return bigints.
28+
29+
We can't mix bigints and regular numbers:
30+
31+
```js run
32+
alert(1n + 2); // Error: Cannot mix BigInt and other types
33+
```
34+
35+
We should explicitly convert them if needed: using either `BigInt()` or `Number()`, like this:
36+
37+
```js run
38+
let bigint = 1n;
39+
let number = 2;
40+
41+
// number to bigint
42+
alert(bigint + BigInt(number)); // 3
43+
44+
// bigint to number
45+
alert(Number(bigint) + number); // 3
46+
```
47+
48+
The conversion of bigint to number is always silent, but if the bigint is too huge and won't fit the number type, then extra bits will be cut off, causing a precision loss.
49+
50+
````smart header="The unary plus is not supported on bigints"
51+
The unary plus operator `+value` is a well-known way to convert `value` to a number.
52+
53+
On bigints it's not supported, to avoid confusion:
54+
```js run
55+
let bigint = 1n;
56+
57+
alert( +bigint ); // error
58+
```
59+
So we should use `Number()` to convert a bigint to a number.
60+
````
61+
62+
## Comparisons
63+
64+
Comparisons, such as `<`, `>` work with bigints and numbers just fine:
65+
66+
```js run
67+
alert( 2n > 1n ); // true
68+
69+
alert( 2n > 1 ); // true
70+
```
71+
72+
As numbers and bigints belong to different types, they can be equal `==`, but not strictly equal `===`:
73+
74+
```js run
75+
alert( 1 == 1n ); // true
76+
77+
alert( 1 === 1n ); // false
78+
```
79+
80+
## Boolean operations
81+
82+
When inside `if` or other boolean operations, bigints behave like numbers.
83+
84+
For instance, in `if`, bigint `0n` is falsy, other values are truthy:
85+
86+
```js run
87+
if (0n) {
88+
// never executes
89+
}
90+
```
91+
92+
Boolean operators, such as `||`, `&&` and others also work with bigints similar to numbers:
93+
94+
```js run
95+
alert( 1n || 2 ); // 1 (1n is considered truthy)
96+
97+
alert( 0n || 2 ); // 2 (0n is considered falsy)
98+
```
99+
100+
## Polyfills
101+
102+
Polyfilling bigints is tricky. The reason is that many JavaScript operators, such as `+`, `-` and so on behave differently with bigints compared to regular numbers.
103+
104+
For example, division of bigints always returns an integer.
105+
106+
To emulate such behavior, a polyfill would need to replace all such operators with its functions. But doing so is cumbersome and would cost a lot of performance.
107+
108+
So, there's no well-known good polyfill.
109+
110+
Although, the other way around is proposed by the developers of [https://github.com/GoogleChromeLabs/jsbi](JSBI) library.
111+
112+
They suggest to use JSBI library calls instead of native bigints:
113+
114+
| Operation | native `BigInt` | JSBI |
115+
|-----------|-----------------|------|
116+
| Creation from Number | `a = BigInt(789)` | `a = JSBI.BigInt(789)` |
117+
| Addition | `c = a + b` | `c = JSBI.add(a, b)` |
118+
| Subtraction | `c = a - b` | `c = JSBI.subtract(a, b)` |
119+
| ... | ... | ... |
120+
121+
...And then use the polyfill (Babel plugin) to convert JSBI calls to native bigints for those browsers that support them.
122+
123+
In other words, this approach suggests that we write code in JSBI instead of native bigints. But JSBI works with numbers as with bigints internally, closely following the specification, so the code will be "bigint-ready".
124+
125+
## References
126+
127+
- [MDN docs on BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt).
128+
- [Specification](https://tc39.es/ecma262/#sec-bigint-objects).
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Character classes
2+
3+
Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79035419441`.
4+
5+
To do so, we can find and remove anything that's not a number. Character classes can help with that.
6+
7+
A *character class* is a special notation that matches any symbol from a certain set.
8+
9+
For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit".
10+
11+
For instance, the let's find the first digit in the phone number:
12+
13+
```js run
14+
let str = "+7(903)-123-45-67";
15+
16+
let regexp = /\d/;
17+
18+
alert( str.match(regexp) ); // 7
19+
```
20+
21+
Without the flag `pattern:g`, the regular expression only looks for the first match, that is the first digit `pattern:\d`.
22+
23+
Let's add the `pattern:g` flag to find all digits:
24+
25+
```js run
26+
let str = "+7(903)-123-45-67";
27+
28+
let regexp = /\d/g;
29+
30+
alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7
31+
32+
// let's make the digits-only phone number of them:
33+
alert( str.match(regexp).join('') ); // 79035419441
34+
```
35+
36+
That was a character class for digits. There are other character classes as well.
37+
38+
Most used are:
39+
40+
`pattern:\d` ("d" is from "digit")
41+
: A digit: a character from `0` to `9`.
42+
43+
`pattern:\s` ("s" is from "space")
44+
: A space symbol: includes spaces, tabs `\t`, newlines `\n` and few other rare characters, such as `\v`, `\f` and `\r`.
45+
46+
`pattern:\w` ("w" is from "word")
47+
: A "wordly" character: either a letter of Latin alphabet or a digit or an underscore `_`. Non-Latin letters (like cyrillic or hindi) do not belong to `pattern:\w`.
48+
49+
For instance, `pattern:\d\s\w` means a "digit" followed by a "space character" followed by a "wordly character", such as `match:1 a`.
50+
51+
**A regexp may contain both regular symbols and character classes.**
52+
53+
For instance, `pattern:CSS\d` matches a string `match:CSS` with a digit after it:
54+
55+
```js run
56+
let str = "Is there CSS4?";
57+
let regexp = /CSS\d/
58+
59+
alert( str.match(regexp) ); // CSS4
60+
```
61+
62+
Also we can use many character classes:
63+
64+
```js run
65+
alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'
66+
```
67+
68+
The match (each regexp character class has the corresponding result character):
69+
70+
![](love-html5-classes.svg)
71+
72+
## Inverse classes
73+
74+
For every character class there exists an "inverse class", denoted with the same letter, but uppercased.
75+
76+
The "inverse" means that it matches all other characters, for instance:
77+
78+
`pattern:\D`
79+
: Non-digit: any character except `pattern:\d`, for instance a letter.
80+
81+
`pattern:\S`
82+
: Non-space: any character except `pattern:\s`, for instance a letter.
83+
84+
`pattern:\W`
85+
: Non-wordly character: anything but `pattern:\w`, e.g a non-latin letter or a space.
86+
87+
In the beginning of the chapter we saw how to make a number-only phone number from a string like `subject:+7(903)-123-45-67`: find all digits and join them.
88+
89+
```js run
90+
let str = "+7(903)-123-45-67";
91+
92+
alert( str.match(/\d/g).join('') ); // 79031234567
93+
```
94+
95+
An alternative, shorter way is to find non-digits `pattern:\D` and remove them from the string:
96+
97+
```js run
98+
let str = "+7(903)-123-45-67";
99+
100+
alert( str.replace(/\D/g, "") ); // 79031234567
101+
```
102+
103+
## A dot is "any character"
104+
105+
A dot `pattern:.` is a special character class that matches "any character except a newline".
106+
107+
For instance:
108+
109+
```js run
110+
alert( "Z".match(/./) ); // Z
111+
```
112+
113+
Or in the middle of a regexp:
114+
115+
```js run
116+
let regexp = /CS.4/;
117+
118+
alert( "CSS4".match(regexp) ); // CSS4
119+
alert( "CS-4".match(regexp) ); // CS-4
120+
alert( "CS 4".match(regexp) ); // CS 4 (space is also a character)
121+
```
122+
123+
Please note that a dot means "any character", but not the "absense of a character". There must be a character to match it:
124+
125+
```js run
126+
alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot
127+
```
128+
129+
### Dot as literally any character with "s" flag
130+
131+
By default, a dot doesn't match the newline character `\n`.
132+
133+
For instance, the regexp `pattern:A.B` matches `match:A`, and then `match:B` with any character between them, except a newline `\n`:
134+
135+
```js run
136+
alert( "A\nB".match(/A.B/) ); // null (no match)
137+
```
138+
139+
There are many situations when we'd like a dot to mean literally "any character", newline included.
140+
141+
That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` matches literally any character:
142+
143+
```js run
144+
alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
145+
```
146+
147+
````warn header="Not supported in Firefox, IE, Edge"
148+
Check <https://caniuse.com/#search=dotall> for the most recent state of support. At the time of writing it doesn't include Firefox, IE, Edge.
149+
150+
Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character".
151+
152+
```js run
153+
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
154+
```
155+
156+
The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter.
157+
158+
This trick works everywhere. Also we can use it if we don't want to set `pattern:s` flag, in cases when we want a regular "no-newline" dot too in the pattern.
159+
````
160+
161+
````warn header="Pay attention to spaces"
162+
Usually we pay little attention to spaces. For us strings `subject:1-5` and `subject:1 - 5` are nearly identical.
163+
164+
But if a regexp doesn't take spaces into account, it may fail to work.
165+
166+
Let's try to find digits separated by a hyphen:
167+
168+
```js run
169+
alert( "1 - 5".match(/\d-\d/) ); // null, no match!
170+
```
171+
172+
Let's fix it adding spaces into the regexp `pattern:\d - \d`:
173+
174+
```js run
175+
alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works
176+
// or we can use \s class:
177+
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works
178+
```
179+
180+
**A space is a character. Equal in importance with any other character.**
181+
182+
We can't add or remove spaces from a regular expression and expect to work the same.
183+
184+
In other words, in a regular expression all characters matter, spaces too.
185+
````
186+
187+
## Summary
188+
189+
There exist following character classes:
190+
191+
- `pattern:\d` -- digits.
192+
- `pattern:\D` -- non-digits.
193+
- `pattern:\s` -- space symbols, tabs, newlines.
194+
- `pattern:\S` -- all but `pattern:\s`.
195+
- `pattern:\w` -- Latin letters, digits, underscore `'_'`.
196+
- `pattern:\W` -- all but `pattern:\w`.
197+
- `pattern:.` -- any character if with the regexp `'s'` flag, otherwise any except a newline `\n`.
198+
199+
...But that's not all!
200+
201+
Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter) it is it a punctuation sign, etc.
202+
203+
We can search by these properties as well. That requires flag `pattern:u`, covered in the next article.
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)