diff --git a/1-js/2-first-steps/8-comparison/1-comparison-questions/solution.md b/1-js/2-first-steps/08-comparison/1-comparison-questions/solution.md similarity index 100% rename from 1-js/2-first-steps/8-comparison/1-comparison-questions/solution.md rename to 1-js/2-first-steps/08-comparison/1-comparison-questions/solution.md diff --git a/1-js/2-first-steps/8-comparison/1-comparison-questions/task.md b/1-js/2-first-steps/08-comparison/1-comparison-questions/task.md similarity index 100% rename from 1-js/2-first-steps/8-comparison/1-comparison-questions/task.md rename to 1-js/2-first-steps/08-comparison/1-comparison-questions/task.md diff --git a/1-js/2-first-steps/8-comparison/article.md b/1-js/2-first-steps/08-comparison/article.md similarity index 100% rename from 1-js/2-first-steps/8-comparison/article.md rename to 1-js/2-first-steps/08-comparison/article.md diff --git a/1-js/2-first-steps/9-uibasic/1-simple-page/solution.md b/1-js/2-first-steps/09-uibasic/1-simple-page/solution.md similarity index 100% rename from 1-js/2-first-steps/9-uibasic/1-simple-page/solution.md rename to 1-js/2-first-steps/09-uibasic/1-simple-page/solution.md diff --git a/1-js/2-first-steps/9-uibasic/1-simple-page/task.md b/1-js/2-first-steps/09-uibasic/1-simple-page/task.md similarity index 100% rename from 1-js/2-first-steps/9-uibasic/1-simple-page/task.md rename to 1-js/2-first-steps/09-uibasic/1-simple-page/task.md diff --git a/1-js/2-first-steps/9-uibasic/article.md b/1-js/2-first-steps/09-uibasic/article.md similarity index 100% rename from 1-js/2-first-steps/9-uibasic/article.md rename to 1-js/2-first-steps/09-uibasic/article.md diff --git a/1-js/2-first-steps/15-function-expressions-arrows/article.md b/1-js/2-first-steps/15-function-expressions-arrows/article.md index a5f6afb2..e68ad66e 100644 --- a/1-js/2-first-steps/15-function-expressions-arrows/article.md +++ b/1-js/2-first-steps/15-function-expressions-arrows/article.md @@ -2,7 +2,7 @@ In Javascript a function is not a "magical language structure", but a special kind of value. -The syntax that we've used before is called *Function Declaration*: +The syntax that we used before is called *Function Declaration*: ```js function sayHi() { @@ -87,8 +87,8 @@ let sayHi = function() { ``` The answer is simple: -- There's no need in `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` and alike. -- A Function Expression appears in the context of the statement: `let sayHi = value;`. It's not a code block. The semicolon `;` is recommended at the end of statements, no matter what is the `value`. So the semicolon here is not related to Function Expression itself in any way, it just terminates the statement. +- There's no need in `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for { }`, `function f { }` etc. +- The Function Expression appears in the context of the statement: `let sayHi = value;`. It's not a code block. The semicolon `;` is recommended at the end of statements, no matter what is the `value`. So the semicolon here is not related to Function Expression itself in any way, it just terminates the statement. ```` diff --git a/1-js/5-data-structures/4-object2/2-is-empty/_js.view/solution.js b/1-js/3-object-basics/1-object/3-is-empty/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/4-object2/2-is-empty/_js.view/solution.js rename to 1-js/3-object-basics/1-object/3-is-empty/_js.view/solution.js diff --git a/1-js/5-data-structures/4-object2/2-is-empty/_js.view/test.js b/1-js/3-object-basics/1-object/3-is-empty/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/4-object2/2-is-empty/_js.view/test.js rename to 1-js/3-object-basics/1-object/3-is-empty/_js.view/test.js diff --git a/1-js/3-object-basics/1-object/3-is-empty/solution.md b/1-js/3-object-basics/1-object/3-is-empty/solution.md new file mode 100644 index 00000000..9e8b3d90 --- /dev/null +++ b/1-js/3-object-basics/1-object/3-is-empty/solution.md @@ -0,0 +1,11 @@ +Just loop over the object and `return false` immediately if there's at least one property. + +```js +function isEmpty(obj) + for(let key in obj) { + return false; + } + return true; +} +``` + diff --git a/1-js/5-data-structures/4-object2/2-is-empty/task.md b/1-js/3-object-basics/1-object/3-is-empty/task.md similarity index 100% rename from 1-js/5-data-structures/4-object2/2-is-empty/task.md rename to 1-js/3-object-basics/1-object/3-is-empty/task.md diff --git a/1-js/3-object-basics/1-object/3-sum-object/solution.md b/1-js/3-object-basics/1-object/4-sum-object/solution.md similarity index 99% rename from 1-js/3-object-basics/1-object/3-sum-object/solution.md rename to 1-js/3-object-basics/1-object/4-sum-object/solution.md index b4607014..eb5b176a 100644 --- a/1-js/3-object-basics/1-object/3-sum-object/solution.md +++ b/1-js/3-object-basics/1-object/4-sum-object/solution.md @@ -1,5 +1,4 @@ - ```js run let salaries = { John: 100, diff --git a/1-js/3-object-basics/1-object/3-sum-object/task.md b/1-js/3-object-basics/1-object/4-sum-object/task.md similarity index 83% rename from 1-js/3-object-basics/1-object/3-sum-object/task.md rename to 1-js/3-object-basics/1-object/4-sum-object/task.md index 0c0e252c..7e3e048d 100644 --- a/1-js/3-object-basics/1-object/3-sum-object/task.md +++ b/1-js/3-object-basics/1-object/4-sum-object/task.md @@ -16,4 +16,4 @@ let salaries = { Write the code to sum all salaries and store in the variable `sum`. Should be `390` in the example above. -Use `for..in` loop to iterate over the object. +If `salaries` is empty, then the result must be `0`. \ No newline at end of file diff --git a/1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/solution.js b/1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/solution.js rename to 1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/solution.js diff --git a/1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/source.js b/1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/source.js similarity index 100% rename from 1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/source.js rename to 1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/source.js diff --git a/1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/test.js b/1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/4-object2/6-multiply-numeric/_js.view/test.js rename to 1-js/3-object-basics/1-object/8-multiply-numeric/_js.view/test.js diff --git a/1-js/5-data-structures/4-object2/3-sum-salaries/solution.md b/1-js/3-object-basics/1-object/8-multiply-numeric/solution.md similarity index 100% rename from 1-js/5-data-structures/4-object2/3-sum-salaries/solution.md rename to 1-js/3-object-basics/1-object/8-multiply-numeric/solution.md diff --git a/1-js/5-data-structures/4-object2/6-multiply-numeric/task.md b/1-js/3-object-basics/1-object/8-multiply-numeric/task.md similarity index 100% rename from 1-js/5-data-structures/4-object2/6-multiply-numeric/task.md rename to 1-js/3-object-basics/1-object/8-multiply-numeric/task.md diff --git a/1-js/3-object-basics/1-object/article.md b/1-js/3-object-basics/1-object/article.md index ce71247c..5b0d6872 100644 --- a/1-js/3-object-basics/1-object/article.md +++ b/1-js/3-object-basics/1-object/article.md @@ -44,7 +44,7 @@ In the `user` object, there are two properties: 1. The first property has the name `"name"` and the value `"John"`. 2. The second one has the name `"age"` and the value `30`. -The `user` object can be imagined as a cabinet with two signed files labelled "name" and "age". +The resulting `user` object can be imagined as a cabinet with two signed files labelled "name" and "age". ![user object](object-user.png) diff --git a/1-js/3-object-basics/2-garbage-collection/article.md b/1-js/3-object-basics/2-garbage-collection/article.md index c95dede8..a4f4b088 100644 --- a/1-js/3-object-basics/2-garbage-collection/article.md +++ b/1-js/3-object-basics/2-garbage-collection/article.md @@ -157,23 +157,23 @@ Regularly the following "garbage collection" steps are performed: For instance, if our object structure might look like this: -![](garbage-collection-0.png) +![](garbage-collection-1.png) Then the first step marks the roots: -![](garbage-collection-1.png) +![](garbage-collection-2.png) Then their references are marked: -![](garbage-collection-2.png) +![](garbage-collection-3.png) ...And their refences, while possible: -![](garbage-collection-3.png) +![](garbage-collection-4.png) Now the objects that could not be visited in the process are considered unreachable and will be removed: -![](garbage-collection-4.png) +![](garbage-collection-5.png) That's the concept how garbage collection works. @@ -182,10 +182,10 @@ Javascript engines apply many optimizations to it, to make it run faster and be Some of the optimizations: - **Generational collection** -- objects are split into two sets: "new ones" and "old ones". Many objects appear, do their job and die fast, so they can be cleaned up more aggressively. Those "new" that survive for long enough, become "old". -- **Incremental collection** -- there may be many objects, if we try to clean up the whole object tree at once, it may take some time and introduce visible delays. So the engine tries to split the job into pieces. Then pieces are executed one at a time. That requires some extra bookkeeping between them. +- **Incremental collection** -- there may be many objects, if we try to clean up the whole object tree at once, it may take some time and introduce visible delays. So the engine tries to split the job into pieces. Then pieces are executed one at a time. That requires some extra bookkeeping in-between to stay consistent. - **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution. -In-depth understanding of the algorithms is also possible, there's no magic, but it requires a lot of under-the-hood digging and -- what's more important, things change, there are ongoing efforts to optimize them. +In-depth understanding of these optimization is also achievable, there's no magic, but it requires a lot of under-the-hood digging. Javascript engines implement them differently. And -- what's even more important, things change, so going that deep is recommended when you already know the language well and really need low-level optimizations for your code. ## Summary @@ -199,6 +199,6 @@ Modern engines implement advanced algorithms of garbage collection. If you are familiar with low-level programming, the more detailed information about V8 garbage collector is in the article [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection). Also you'd better prepare yourself by learning how values are stored in V8. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, things are partially similar, but not the same. -In-depth knowledge of engines is good when you need low-level optimizations. It would be a great next step after you're familiar with the language. +In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language. And when you feel that you need that of course. diff --git a/1-js/3-object-basics/2-garbage-collection/family.png b/1-js/3-object-basics/2-garbage-collection/family.png index b1cc0a1a..dbbc01d2 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/family.png and b/1-js/3-object-basics/2-garbage-collection/family.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/family@2x.png b/1-js/3-object-basics/2-garbage-collection/family@2x.png index 16542fc9..64b4619b 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/family@2x.png and b/1-js/3-object-basics/2-garbage-collection/family@2x.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-0.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-0.png deleted file mode 100644 index f3bde13e..00000000 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-0.png and /dev/null differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-0@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-0@2x.png deleted file mode 100644 index 401148b3..00000000 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-0@2x.png and /dev/null differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-1.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-1.png index f74678bf..42319177 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-1.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-1.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-1@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-1@2x.png index 0b971c3f..223ea32a 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-1@2x.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-1@2x.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-2.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-2.png index 58267192..da63d396 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-2.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-2.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-2@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-2@2x.png index c5deacfc..1f614e3e 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-2@2x.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-2@2x.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-3.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-3.png index e71dc01d..e77144c1 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-3.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-3.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-3@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-3@2x.png index 2ba50331..37e349b6 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-3@2x.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-3@2x.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-4.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-4.png index a5a6a69e..110e0d9c 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-4.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-4.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-4@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-4@2x.png index 72c2f6b3..c09d75f9 100644 Binary files a/1-js/3-object-basics/2-garbage-collection/garbage-collection-4@2x.png and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-4@2x.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-5.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-5.png new file mode 100644 index 00000000..bc4ea967 Binary files /dev/null and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-5.png differ diff --git a/1-js/3-object-basics/2-garbage-collection/garbage-collection-5@2x.png b/1-js/3-object-basics/2-garbage-collection/garbage-collection-5@2x.png new file mode 100644 index 00000000..0ab697e6 Binary files /dev/null and b/1-js/3-object-basics/2-garbage-collection/garbage-collection-5@2x.png differ diff --git a/1-js/3-object-basics/3-object-methods/article.md b/1-js/3-object-basics/3-object-methods/article.md index 10c9c32b..ff049d75 100644 --- a/1-js/3-object-basics/3-object-methods/article.md +++ b/1-js/3-object-basics/3-object-methods/article.md @@ -281,83 +281,6 @@ Any other operation like assignment `hi = user.hi` discards the reference type a So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj[method]()` syntax (they do the same here). -## Explicit "this" with "call/apply" [#call-apply] - -The value of `this` does not have to come from the aforementioned rules. - -We can explicitly set it to any object using `func.call`. - -The syntax is: - -```js -func.call(context, arg1, arg2, ...) -``` - -For instance: - -```js run -function sayHi() { - alert(this.name); -} - -let user = { name: "John" }; -let admin = { name: "Admin" }; - -// use call to pass different objects as "this" -sayHi.call( user ); // John -sayHi.call( admin ); // Admin -``` - -The first parameter of `call` is the intended value of `"this"`, the latter are arguments. - -So `sayHi.call(admin)` runs the function `sayHi` with `this = admin`, hence `this.name` in it becomes `"Admin"`. - -These calls are roughly equivalent: -```js -func(1, 2, 3); -func.call(obj, 1, 2, 3) -``` - -They both call `func` with arguments `1`, `2` and `3`. The only difference is that `call` also sets `"this"`. - -The method `func.call` is used when we'd like to use a function in the context of different objects, but do not want to actually assign it to them. We'll see more examples of it soon. - -### "func.apply" - -There's also a similar method `func.apply`: - -```js -func.apply(context, args) -``` - -It does the same as `call`: executes the function providing `context` as `this`, but where `call` awaits a list of arguments, `apply` awaits an array. - -These two calls do the same: - -```js -func.call(obj, 1, 2, 3); -func.apply(obj, [1, 2, 3]); -``` - -In old times `apply` was more powerful, because it allows to create the array of arguments dynamically. Their number is not hardcoded at code-write time. - -But in the modern language, we have the spread operator `'...'` and can use it to convert an array into a list of for `call`, so these two are equal: - -```js -let args = [1, 2, 3]; - -func.call(obj, ...args); -func.apply(obj, args); -``` - -Nowadays the use of `apply` or `call` is mainly a metter of personal preference. But `apply` is somewhat better optimized in engines than the call + spread combination, because it exists longer. So it would execute a little bit faster. - -## Binding "this" with "bind" - -There's still a way to bind "this" to a function. - -[todo] migrate bind here???? - ## Summary diff --git a/1-js/3-object-basics/6-object-toprimitive/article.md b/1-js/3-object-basics/6-object-toprimitive/article.md index 089bf21a..6dd05ac5 100644 --- a/1-js/3-object-basics/6-object-toprimitive/article.md +++ b/1-js/3-object-basics/6-object-toprimitive/article.md @@ -23,10 +23,8 @@ Most of the time, it's more flexible and gives more readable code to explicitly That said, there are still valid reasons why we should know how it works. - The `alert(user)` kind of output is still used for logging and debugging. -- The built-in `toString` method of objects allows to get the type of almost anything. - Sometimes it just happens (on mistake?), and we should understand what's going on. - ## ToPrimitive When an object is used as a primitive, the special internal algorithm named [ToPrimitive](https://tc39.github.io/ecma262/#sec-toprimitive) is invoked. @@ -167,73 +165,5 @@ if ({}) alert("true"); // works That is not customizable. ```` -## Bonus: toString for the type - -There are many kinds of built-in objects in Javascript. Many of them have own implementations of `toString` and `valueOf`. We'll see them when we get to them. - -But the built-in `toString()` of plain objects is also interesting, it does something very special. - -From the first sight it's obvious: - -```js run -let obj = { }; - -alert( obj ); // [object Object] -``` - -But it's much more powerful than that. - -By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), `toString` can work in the context of any value. And it returns `[object ...]` with the kind of the value inside. - -The algorithm looks like this: - -- If `this` value is `undefined`, return `[object Undefined]` -- If `this` value is `null`, return `[object Null]` -- If `this` is a function, return `[object Function]` -- ...Some other builtin cases for strings, numbers etc... -- Otherwise if there's a property `obj[Symbol.toStringTag]`, then return it inside `[object...]`. -- Otherwise, return `[object Object]`. - -Most environment-specific objects even if they do not belong to Javascript core, like `window` in the browser or `process` in Node.JS, have `Symbol.toStringTag` property. So this algorithm works for them too. - -To make use of it, we should pass the thing to examine as `this`. We can do it using [func.call](info:object-methods#call-apply). - -```js run -let s = {}.toString; // copy toString of a plain object into a variable - -// call the algorithm with this = null -alert( s.call(null) ); // [object Null] - -// call the algorithm with this = alert -alert( s.call(alert) ); // [object Function] - -// browser object works too -alert( s.call(window) ); // [object Window] -// (because it has Symbol.toStringTag) -alert( window[Symbol.toStringTag] ); // Window -``` - -There might be a question: "Why [object Null]?". Well, of course, `null` is not an object. The wrapper `[object ...]` is the same for historical reasons and for making things universal. - -In the example above we copy the "original" `toString` method of a plain object to the variable `s`, and then use it to make sure that we use *exactly that* `toString`. - -We could also call it directly: -```js run -alert( {}.toString.call("test") ); // [object String] -``` - -So, `{}.toString` can serve as "`typeof` on steroids" -- the more powerful version of type detection that not only distinguishes between basic language types, but also returns the kind of an object. - -Most builtins have `Symbol.toStringTag` property, for our objects we can provide it too: - -```js run -let user = { - [Symbol.toStringTag]: "User" -}; - -alert( {}.toString.call(user) ); // [object User] -``` - - diff --git a/1-js/3-object-basics/7-array/article.md b/1-js/3-object-basics/7-array/article.md index 7b8427c7..dd7a911e 100644 --- a/1-js/3-object-basics/7-array/article.md +++ b/1-js/3-object-basics/7-array/article.md @@ -431,7 +431,6 @@ alert( "1" + 1 ); // "11" alert( "1,2" + 1 ); // "1,21" ``` - ## Summary Array is a special kind of objects, suited to store and manage ordered data items. @@ -463,5 +462,5 @@ To loop over the elements of the array: - `for(let item of arr)` -- the modern syntax for items only, - `for(let i in arr)` -- never use. +We will return to arrays and study more methods to add, remove, extract elements and sort arrays in the chapter . -That were the "extended basics". There are more methods, and in the future chapter we will return to them. diff --git a/1-js/3-object-basics/8-iterable/article.md b/1-js/3-object-basics/8-iterable/article.md index e0de522f..04949a57 100644 --- a/1-js/3-object-basics/8-iterable/article.md +++ b/1-js/3-object-basics/8-iterable/article.md @@ -180,9 +180,28 @@ alert(arr.pop()); // World (method works) ```js // assuming that range is taken from the example above let arr = Array.from(range); -alert(arr); // 1,2,3,4,5 (toString of Array gives a list of items) +alert(arr); // 1,2,3,4,5 ``` +The full syntax for `Array.from` allows to provide an optional "mapping" function: +```js +Array.from(obj[, mapFn, thisArg]) +``` + +The second argument `mapFn` should be the function to apply to each element before adding to the array, and `thisArg` allows to set `this` for it. + +For instance: + +```js +// assuming that range is taken from the example above + +// square each number +let arr = Array.from(range, num => num * num); + +alert(arr); // 1,4,9,16,25 +``` + + ## Summary Objects that can be used in `for..of` are called *iterable*. @@ -197,6 +216,6 @@ The modern specification mostly uses iterables instead of arrays where an ordere Objects that have indexed properties and `length` are called *array-like*. Such objects may also have other properties and methods, but lack built-in methods of arrays. -`Array.from(obj)` makes a real `Array` of an iterable or array-like `obj`, and then we can use array methods on it. +`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and then we can use array methods on it. The optional arguments `mapFn` and `thisArg` allow to apply a function to each item. diff --git a/1-js/4-more-syntax/1-function-arguments-rest-spread/article.md b/1-js/4-more-syntax/1-function-arguments-rest-spread/article.md new file mode 100644 index 00000000..2cf4d544 --- /dev/null +++ b/1-js/4-more-syntax/1-function-arguments-rest-spread/article.md @@ -0,0 +1,203 @@ +# Function arguments: rest and spread + +In Javascript, there is an internal type named [List](https://tc39.github.io/ecma262/#sec-list-and-record-specification-type). + +When a function is called, it is said to have "a list of parameters". That's not a figure of speech. The specification officially says that in the call `f(a, b, c)` we have the function `f` the list of `(a, b, c)`. + +[cut] + +Both List and Array represent ordered collections of values. + +The difference is: + +- `Array` is the open data type that we can use, it provides special methods like `push/pop`. +- `List` is the internal type, to represend lists of arguments and such, it has no special methods. + +There are two use cases when we want to convert between them: + +1. To work with an arbitrary number of function arguments, it's useful to have them in the form of array. +2. We have an array of values and would like to call a function that requires them to be listed. + +Both variants are possible. + +## Rest parameters `...` + +The rest parameters are denoted with three dots `...`. They literally mean: "gather the list into an array". + +For instance, here we gather all arguments into array `args`: + +```js run +function sumAll(...args) { // args is the name for the array + let sum = 0; + + for(let arg of args) sum += arg; + + return sum; +} + +alert( sumAll(1) ); // 1 +alert( sumAll(1, 2) ); // 3 +alert( sumAll(1, 2, 3) ); // 6 +``` + +That also works partially. + +For instance, here we put few first arguments into variables and gather only the rest of them: + +```js run +function showName(firstName, lastName, ...rest) { + alert( firstName + ' ' + lastName ); // Julius Caesar + + // the rest = ["Consul", "of the Roman Republic"] + alert( rest[0] ); // Consul + alert( rest[1] ); // of the Roman Republic + alert( rest.length ); // 2 +} + +showName("Julius", "Caesar", "Consul", "of the Roman Republic"); +``` + +````warn header="The rest parameters must be at the end" +The rest parameters gather all remaining arguments, so the following has no sense: + +```js +function f(arg1, ...rest, arg2) { // arg2 after ...rest ?! + // error +} +``` + +The `...rest` must always be the last. +```` + +## The "arguments" variable + +But there is also a special array-like object named `arguments` that contains all arguments by their index. + +For instance: + +```js run +function showName() { + alert( arguments[0] ); + alert( arguments[1] ); + alert( arguments.length ); + + // iterable too + // for(let arg of arguments) alert(arg); +} + +// shows: Julius, Caesar, 2 +showName("Julius", "Caesar"); + +// shows: Ilya, undefined, 1 +showName("Ilya"); +``` + +In old times, rest parameters did not exist in the language, and `arguments` was the only way to get *all arguments* of the function no matter of their total number. + +And it still works. + +But the downside is that though `arguments` is both array-like and iterable, it's not an array. It does not support array methods. Also, it always has everything in it, we can't get first parameters in the variable and keep only the rest in arguments. + +So when we need these features, then rest parameters are preferred. + +## Spread operator [#spread-operator] + +We've just seen how to get an array from the list of parameters. + +Now let's do the reverse. + +For instance, there's a built-in function [Math.max](mdn:js/Math/max) that returns the greatest number from the list: + +```js run +alert( Math.max(3, 5, 1) ); // 5 +``` + +Now let's say we have an array `[3, 5, 1]`. How to call `Math.max` with it? + +Passing it "as it" won't work, because `Math.max` expects a list of numeric arguments, not a single array: + +```js run +let arr = [3, 5, 1]; + +*!* +alert( Math.max(arr) ); // NaN +*/!* +``` + +Most of the time we also can't manually list items in the code `Math.max(arg[0], arg[1], arg[2])`, because their exact number is not known. As our script executes, there might be many, or there might be none. + +*Spread operator* to the rescue. It looks similar to rest parameters, also using `...`, but does quite the opposite. + +When `...iter` is used in the function call, it "expands" an iterable object `iter` into the list. + +For `Math.max`: + +```js run +let arr = [3, 5, 1]; + +alert( Math.max(...arr) ); // 5 +``` + +Unlike rest parameters, there is no restrictions of now many iterables we use. + +Here's example of a combination: + +```js run +let arr = [3, 5, 1]; +let arr2 = [8, 9, 15]; + +*!* +alert( Math.max(0, ...arr, 2, ...arr2) ); // 15 +*/!* +``` + +```smart header="Spread or rest?" +When you see `"..."`, there's an easy way to differ spread operator from rest parameters: + +- Rest parameters, if it's in the function definition (gathers into array). +- Spread operator, if anywhere else (expands an array). +``` + +Also we can use spread operator to merge arrays: + +```js run +let arr = [3, 5, 1]; +let arr2 = [8, 9, 15]; + +*!* +let merged = [0, ...arr, 2, ...arr2]; +*/!* + +alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2) +``` + + +In the examples above we used an array, but any iterable will do including strings: + +```js run +let str = "Hello"; + +alert( [...str] ); // H,e,l,l,o +``` + +The spread operator `...str` actually does the same as `for..of` to gather elements. For a string, `for..of` returns characters one by one. And then it passes them as a list to array initializer `["h","e","l","l","o"]`. + +If our purpose is only to convert an iterable to array, then we can also use `Array.from`: + +```js run +let str = "Hello"; + +// Array.from converts an iterable into an array +alert( Array.from(str) ); // H,e,l,l,o +``` + + + +## Summary + +- When `...` occurs in function parameters, it's "rest parameters" and gathers the rest of the list into the array. +- When `...` occurs anywhere else, it's called a "spread operator" and expands an array into the list. + +Together they help to travel between a list and an array of parameters with ease. + +All arguments of a function call are also available in the `arguments` array-like iterable object. diff --git a/archive/11-destructuring/1-destructuring-assignment/solution.md b/1-js/4-more-syntax/2-destructuring-assignment/1-destructuring-assignment/solution.md similarity index 100% rename from archive/11-destructuring/1-destructuring-assignment/solution.md rename to 1-js/4-more-syntax/2-destructuring-assignment/1-destructuring-assignment/solution.md diff --git a/archive/11-destructuring/1-destructuring-assignment/task.md b/1-js/4-more-syntax/2-destructuring-assignment/1-destructuring-assignment/task.md similarity index 100% rename from archive/11-destructuring/1-destructuring-assignment/task.md rename to 1-js/4-more-syntax/2-destructuring-assignment/1-destructuring-assignment/task.md diff --git a/archive/11-destructuring/article.md b/1-js/4-more-syntax/2-destructuring-assignment/article.md similarity index 62% rename from archive/11-destructuring/article.md rename to 1-js/4-more-syntax/2-destructuring-assignment/article.md index f58af9b9..a66f3733 100644 --- a/archive/11-destructuring/article.md +++ b/1-js/4-more-syntax/2-destructuring-assignment/article.md @@ -1,6 +1,6 @@ -# Destructuring +# Destructuring assignment -Destructuring assignment is a special syntax for assignments that allows to immediately split an array or a complex object into variables. +*Destructuring assignment* is a special syntax for assignments that allows to immediately split an array or a complex object into variables. [cut] @@ -23,7 +23,7 @@ alert(surname); // Kantor The destructuring assignment puts the first value of the array into the variable `firstName` and the second one into `surname`. Any other array elements (if exist) are ignored. -Note that the array itself is not modified in the process. +Note that the word "destructuring" may be a bit too fearful. It doesn't destroy anything. The array `arr` is not modified in the process. It just "unpacks" the array into variables. ````smart header="Ignore first elements" Unwanted elements of the array can also be thrown away via an extra comma: @@ -42,7 +42,7 @@ In the code above, the first and second elements of the array are skipped, the t ### The rest operator -If we want to get all following values of the array, but are not sure of their number -- we can add one more parameter that gets "the rest" using the rest operator `"..."` (three dots): +If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using the rest operator `"..."` (three dots): ```js run *!* @@ -51,13 +51,16 @@ let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Repub alert(name1); // Julius alert(name2); // Caesar + +*!* alert(rest[0]); // Consul alert(rest[1]); // of the Roman Republic +*/!* ``` -The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, the operator is three dots. It must be the last element of the destructuring assignment. +The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, the operator is three dots. The rest operator must be the last in the destructuring assignment. -### The default values +### Default values The there are less values in the array than variables in the assignment -- there will be no error, absent values are considered undefined: @@ -113,10 +116,10 @@ alert(width); // 100 alert(height); // 200 ``` -Properties `options.title`, `options.width` and `options.height` are automcatically assigned to the corresponding variables. The order of propertiies does not matter, that works too: +Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter, that works too: ```js -// let {title, width, height} +// changed the order of properties in let {...} let {height, width, title} = { title: "Menu", height: 200, width: 100 } ``` @@ -130,10 +133,14 @@ let options = { }; *!* -// { source property: target variable } +// { sourceProperty: targetVariable } let {width: w, height: h, title} = options; */!* +// width -> w +// height -> h +// title -> title + alert(title); // Menu alert(w); // 100 alert(h); // 200 @@ -141,7 +148,7 @@ alert(h); // 200 The colon shows "what : goes where". In the example above the property `width` goes to `w`, property `height` goes to `h`, and `title` is assigned to the same name. -If some properties are absent, we can set default values using `=`, like this: +If some properties are absent, we can set default values using `"="`, like this: ```js run let options = { @@ -188,7 +195,7 @@ let title, width, height; {title, width, height} = {title: "Menu", width: 200, height: 100}; ``` -The problem is that Javascript treats `{...}` in the main code flow (not inside another expression) as a code block. Such standalone code blocks are rarely used, but in theory can group statements, like this: +The problem is that Javascript treats `{...}` in the main code flow (not inside another expression) as a code block. Such standalone code blocks are rarely used, but can group statements, like this: ```js run { @@ -199,13 +206,14 @@ The problem is that Javascript treats `{...}` in the main code flow (not inside } ``` -To show Javascript that it's not a code block, we can wrap the whole assignment in brackets `(...)`: +To show Javascript that it's not a code block, but a something else, we can wrap the whole assignment in brackets `(...)`: ```js run let title, width, height; -// okay now +// starts with a bracket, so it's not a code block +// now Javascript will see the destructuring assignment *!*(*/!*{title, width, height} = {title: "Menu", width: 200, height: 100}*!*)*/!*; alert( title ); // Menu @@ -248,6 +256,103 @@ As we can see, the whole `options` object is correctly assigned to variables. The left part of the destructuring assignment can combine and nest things as needed. +## Destructuring function parameters + +There are times when a function may have many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, items list and so on. + +Here's a bad way to write such function: + +```js +function showMenu(title = "Untitled", width = 200, height = 100, items = []) { + // ... +} +``` + +The real-life problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default. + +Like this? + +```js +showMenu("My Menu", undefined, undefined, ["Item1", "Item2"]) +``` + +That's ugly. And becomes unreadable when we deal with more parameters. + +Destructuring comes to the rescue! + +We can pass parameters as an object, and the function immediately destructurizes them into variables: + +```js run +let options = { + title: "My menu", + items: ["Item1", "Item2"] +}; + +*!* +function showMenu({title = "Untitled", width = 200, height = 100, items = []}) { +*/!* + alert( title + ' ' + width + ' ' + height ); // My Menu 100 200 + alert( items ); // Item1, Item2 +} + +showMenu(options); +``` + +We can also use the more complex destructuring with nestings and colon mappings: + +```js run +let options = { + title: "My menu", + items: ["Item1", "Item2"] +}; + +*!* +function showMenu({ + title = "Untitled", + width:w = 100, // width goes to w + height:h = 200, // height goes to h + items: [item1, item2] // items first element goes to item1, second to item2 +}) { +*/!* + alert( title + ' ' + w + ' ' + h ); // My Menu 100 200 + alert( item1 ); // Item1 + alert( item2 ); // Item2 +} + +showMenu(options); +``` + +The syntax is the same as for a destructuring assignment: +```js +function({ + incomingProperty: parameterName = defaultValue + ... +}) +``` + +Please note that such destructuring assumes that `showMenu()` does have an argument. If we want all values by default, then we should specify an empty object: + +```js +showMenu({}); + +// that would give an error +showMenu(); +``` + +We can fix this by making `{}` a value by default for the whole destructuring thing: + + +```js run +// simplified parameters a bit for clarity +function showMenu(*!*{ title="Menu", width=100, height=200 } = {}*/!*) { + alert( title + ' ' + width + ' ' + height ); +} + +showMenu(); // Menu 100 200 +``` + +In the code above, the whole arguments object is `{}` by default, so there's always something to destructurize. + ## Summary - Destructuring assignment allows to instantly map an object or array into many variables. diff --git a/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/solution.md b/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/solution.md new file mode 100644 index 00000000..36f90e4c --- /dev/null +++ b/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/solution.md @@ -0,0 +1,16 @@ + +That's because `arr.keys()` returns an iterable, but not an array. + +We can convert it into an array using `Array.from`: + + +```js run +let arr = []; +arr[5] = true; + +*!* +let numbers = Array.from(arr.keys()); +*/!* +numbers.push(6); +alert(numbers); // 0,1,2,3,4,5,6 +``` diff --git a/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/task.md b/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/task.md new file mode 100644 index 00000000..de246abe --- /dev/null +++ b/1-js/4-more-syntax/3-advanced-loops/1-iterable-keys/task.md @@ -0,0 +1,28 @@ +importance: 5 + +--- + +# Iterable keys + +We want to get an array of numbers `0,1,2,3,4,5`. + +The call to `arr.keys()` can be used, but there's a problem: + +```js run +let arr = []; +arr[5] = true; + +// loop works +for(let number of arr.keys()) { + alert(number); // 0,1,2,3,4,5 +} + + +let numbers = arr.keys(); +*!* +// Error: numbers.push is not a function +numbers.push(6); +*/!* +``` + +Why? How can we fix the code to let `numbers.push` work on the last one? \ No newline at end of file diff --git a/1-js/5-data-structures/4-object2/3-sum-salaries/_js.view/solution.js b/1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/4-object2/3-sum-salaries/_js.view/solution.js rename to 1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/_js.view/solution.js diff --git a/1-js/5-data-structures/4-object2/3-sum-salaries/_js.view/test.js b/1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/4-object2/3-sum-salaries/_js.view/test.js rename to 1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/_js.view/test.js diff --git a/1-js/5-data-structures/4-object2/4-max-salary/solution.md b/1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/solution.md similarity index 100% rename from 1-js/5-data-structures/4-object2/4-max-salary/solution.md rename to 1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/solution.md diff --git a/1-js/5-data-structures/4-object2/3-sum-salaries/task.md b/1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/task.md similarity index 100% rename from 1-js/5-data-structures/4-object2/3-sum-salaries/task.md rename to 1-js/4-more-syntax/3-advanced-loops/5-sum-salaries/task.md diff --git a/1-js/5-data-structures/4-object2/4-max-salary/_js.view/solution.js b/1-js/4-more-syntax/3-advanced-loops/6-max-salary/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/4-object2/4-max-salary/_js.view/solution.js rename to 1-js/4-more-syntax/3-advanced-loops/6-max-salary/_js.view/solution.js diff --git a/1-js/5-data-structures/4-object2/4-max-salary/_js.view/test.js b/1-js/4-more-syntax/3-advanced-loops/6-max-salary/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/4-object2/4-max-salary/_js.view/test.js rename to 1-js/4-more-syntax/3-advanced-loops/6-max-salary/_js.view/test.js diff --git a/1-js/5-data-structures/4-object2/5-count-properties/solution.md b/1-js/4-more-syntax/3-advanced-loops/6-max-salary/solution.md similarity index 100% rename from 1-js/5-data-structures/4-object2/5-count-properties/solution.md rename to 1-js/4-more-syntax/3-advanced-loops/6-max-salary/solution.md diff --git a/1-js/5-data-structures/4-object2/4-max-salary/task.md b/1-js/4-more-syntax/3-advanced-loops/6-max-salary/task.md similarity index 100% rename from 1-js/5-data-structures/4-object2/4-max-salary/task.md rename to 1-js/4-more-syntax/3-advanced-loops/6-max-salary/task.md diff --git a/1-js/5-data-structures/4-object2/5-count-properties/_js.view/solution.js b/1-js/4-more-syntax/3-advanced-loops/7-count-properties/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/4-object2/5-count-properties/_js.view/solution.js rename to 1-js/4-more-syntax/3-advanced-loops/7-count-properties/_js.view/solution.js diff --git a/1-js/5-data-structures/4-object2/5-count-properties/_js.view/test.js b/1-js/4-more-syntax/3-advanced-loops/7-count-properties/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/4-object2/5-count-properties/_js.view/test.js rename to 1-js/4-more-syntax/3-advanced-loops/7-count-properties/_js.view/test.js diff --git a/1-js/5-data-structures/4-object2/6-multiply-numeric/solution.md b/1-js/4-more-syntax/3-advanced-loops/7-count-properties/solution.md similarity index 100% rename from 1-js/5-data-structures/4-object2/6-multiply-numeric/solution.md rename to 1-js/4-more-syntax/3-advanced-loops/7-count-properties/solution.md diff --git a/1-js/5-data-structures/4-object2/5-count-properties/task.md b/1-js/4-more-syntax/3-advanced-loops/7-count-properties/task.md similarity index 100% rename from 1-js/5-data-structures/4-object2/5-count-properties/task.md rename to 1-js/4-more-syntax/3-advanced-loops/7-count-properties/task.md diff --git a/1-js/4-more-syntax/3-advanced-loops/article.md b/1-js/4-more-syntax/3-advanced-loops/article.md new file mode 100644 index 00000000..d2a651bd --- /dev/null +++ b/1-js/4-more-syntax/3-advanced-loops/article.md @@ -0,0 +1,143 @@ + +# Advanced loops + +Now as we know arrays, iterables and destructuring, we're ready to understand cover few more forms of loops. + + +## Over objects + +We've already seen one of the most popular loops: `for..in` + +```js +for(let key in obj) { + // key iterates over object keys +} +``` + +But there are also ways to get keys, values or or key/value pairs as arrays: + +- [Object.keys(obj)](mdn:js/Object/keys) -- returns the array of keys. +- [Object.values(obj)](mdn:js/Object/values) -- returns the array of values. +- [Object.entries(obj)](mdn:js/Object/entries) -- returns the array of `[key, value]` pairs. + +For instance: + +```js +let user = { + name: "John", + age: 30 +}; +``` + +- `Object.keys(user) = [name, age]` +- `Object.values(user) = ["John", 30]` +- `Object.entries(user) = [ ["name","John"], ["age",30] ]` + + +We can use `Object.values` to iterate over object values: + +```js +for(let value of Object.values(obj)) { + // value iterates over object values +} +``` + +Here `Object.values(obj)` returns the array of properties, and `for..of` iterates over the array. + +Also we can combine destructuring with `Object.entries` to iterate over key/value pairs: + +```js +for(let [key, value] of Object.entries(obj)) { + // key,value iterate over properties +} +``` + +The example of all 3 loops: + +```js run +let user = { + name: "John", + age: 30 +}; + +// over keys +for(let key in user) { + alert(key); // name, then age + // can get the values with user[key] +} + +// over values +for(let value of Object.values(user)) { + alert(value); // John, then 30 +} + +// over key/value pairs +for(let [key, value] of Object.entries(user)) { + alert(key + ':' + value); // name:John, then age:30 +} +``` + + +```smart header="The loops ignore symbolic properties" +All 3 forms of loops (and the given `Object` methods) ignore properties that use `Symbol(...)` as keys. + +That's an expected behavior, because symbols are often created to make sure that the property can not be accessed accidentaly. There is a separate method named [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys (if we really know what we're doing). Also, the method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) returns all keys. +``` + +## Over arrays + +There are many data structures that keep keys and/or values. `Object` is one of them, `Array` is the other one, and we'll see more in the future. + +The method names `keys()`, `values()` and `entries()` are generic, there is a common agreement to use them for common iterations. + +For arrays: + +- [arr.keys()](mdn:js/Array/keys) -- returns the iterable for keys (indexes). +- [arr.entries()](mdn:js/Array/entries) -- returns the iterable for `[index, value]` pairs. + +There is no `arr.values()`, because `for..of` iterates over values already. + +Note that for arrays and further data structures the methods are callable directly, and they return iterables, not arrays. + +The loops: + +```js run +let users = ["John", "Pete", "Ann"]; + +// over keys (indexes) +for(let key of users.keys()) { + alert(key); // 0, 1, 2 +} + +// over values, basic for..of (no special method) +for(let value of users) { + alert(value); // John, then 30 +} + +// over key/value pairs +for(let [key, value] of users.entries()) { + alert(key + ':' + value); // 0:John, then 1:Pete, 2:Ann +} +``` + +````smart header="No holes" +All these methods treat arrays as contiguous. "Holes" are considered `undefined` items. + +```js run +let arr = []; +arr[4] = "test"; + +*!* +// all keys till arr.length +*/!* +for(let i of arr.keys()) alert(i); // 0,1,2,3,4 +alert(`Length: ${arr.length}`); // 5, remember, length is the last index + 1 +``` + +```` + + + + + + diff --git a/1-js/4-more-syntax/index.md b/1-js/4-more-syntax/index.md new file mode 100644 index 00000000..2ddf0d29 --- /dev/null +++ b/1-js/4-more-syntax/index.md @@ -0,0 +1 @@ +# More syntax diff --git a/1-js/4-code-quality/1-debugging-chrome/article.md b/1-js/5-code-quality/1-debugging-chrome/article.md similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/article.md rename to 1-js/5-code-quality/1-debugging-chrome/article.md diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_break_error.png b/1-js/5-code-quality/1-debugging-chrome/chrome_break_error.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_break_error.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_break_error.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_break_error@2x.png b/1-js/5-code-quality/1-debugging-chrome/chrome_break_error@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_break_error@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_break_error@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources@2x.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_break.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_break.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_break.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_break.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_break@2x.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_break@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_break@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_break@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_buttons.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_buttons.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_buttons.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_buttons.png diff --git a/1-js/4-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png b/1-js/5-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/console_error.png b/1-js/5-code-quality/1-debugging-chrome/console_error.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/console_error.png rename to 1-js/5-code-quality/1-debugging-chrome/console_error.png diff --git a/1-js/4-code-quality/1-debugging-chrome/console_error@2x.png b/1-js/5-code-quality/1-debugging-chrome/console_error@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/console_error@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/console_error@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/debugging.view/index.html b/1-js/5-code-quality/1-debugging-chrome/debugging.view/index.html similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/debugging.view/index.html rename to 1-js/5-code-quality/1-debugging-chrome/debugging.view/index.html diff --git a/1-js/4-code-quality/1-debugging-chrome/debugging.view/pow.js b/1-js/5-code-quality/1-debugging-chrome/debugging.view/pow.js similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/debugging.view/pow.js rename to 1-js/5-code-quality/1-debugging-chrome/debugging.view/pow.js diff --git a/1-js/4-code-quality/1-debugging-chrome/error.view/index.html b/1-js/5-code-quality/1-debugging-chrome/error.view/index.html similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/error.view/index.html rename to 1-js/5-code-quality/1-debugging-chrome/error.view/index.html diff --git a/1-js/4-code-quality/1-debugging-chrome/error.view/pow.js b/1-js/5-code-quality/1-debugging-chrome/error.view/pow.js similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/error.view/pow.js rename to 1-js/5-code-quality/1-debugging-chrome/error.view/pow.js diff --git a/1-js/4-code-quality/1-debugging-chrome/head.html b/1-js/5-code-quality/1-debugging-chrome/head.html similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/head.html rename to 1-js/5-code-quality/1-debugging-chrome/head.html diff --git a/1-js/4-code-quality/1-debugging-chrome/manage1.png b/1-js/5-code-quality/1-debugging-chrome/manage1.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage1.png rename to 1-js/5-code-quality/1-debugging-chrome/manage1.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage1@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage1@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage1@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage1@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage2.png b/1-js/5-code-quality/1-debugging-chrome/manage2.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage2.png rename to 1-js/5-code-quality/1-debugging-chrome/manage2.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage2@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage2@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage2@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage2@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage3.png b/1-js/5-code-quality/1-debugging-chrome/manage3.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage3.png rename to 1-js/5-code-quality/1-debugging-chrome/manage3.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage3@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage3@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage3@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage3@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage4.png b/1-js/5-code-quality/1-debugging-chrome/manage4.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage4.png rename to 1-js/5-code-quality/1-debugging-chrome/manage4.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage4@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage4@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage4@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage4@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage5.png b/1-js/5-code-quality/1-debugging-chrome/manage5.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage5.png rename to 1-js/5-code-quality/1-debugging-chrome/manage5.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage5@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage5@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage5@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage5@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage6.png b/1-js/5-code-quality/1-debugging-chrome/manage6.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage6.png rename to 1-js/5-code-quality/1-debugging-chrome/manage6.png diff --git a/1-js/4-code-quality/1-debugging-chrome/manage6@2x.png b/1-js/5-code-quality/1-debugging-chrome/manage6@2x.png similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/manage6@2x.png rename to 1-js/5-code-quality/1-debugging-chrome/manage6@2x.png diff --git a/1-js/4-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg b/1-js/5-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg similarity index 100% rename from 1-js/4-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg rename to 1-js/5-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg diff --git a/1-js/4-code-quality/2-coding-style/1-style-errors/solution.md b/1-js/5-code-quality/2-coding-style/1-style-errors/solution.md similarity index 100% rename from 1-js/4-code-quality/2-coding-style/1-style-errors/solution.md rename to 1-js/5-code-quality/2-coding-style/1-style-errors/solution.md diff --git a/1-js/4-code-quality/2-coding-style/1-style-errors/task.md b/1-js/5-code-quality/2-coding-style/1-style-errors/task.md similarity index 100% rename from 1-js/4-code-quality/2-coding-style/1-style-errors/task.md rename to 1-js/5-code-quality/2-coding-style/1-style-errors/task.md diff --git a/1-js/4-code-quality/2-coding-style/article.md b/1-js/5-code-quality/2-coding-style/article.md similarity index 100% rename from 1-js/4-code-quality/2-coding-style/article.md rename to 1-js/5-code-quality/2-coding-style/article.md diff --git a/1-js/4-code-quality/2-coding-style/code-style.png b/1-js/5-code-quality/2-coding-style/code-style.png similarity index 100% rename from 1-js/4-code-quality/2-coding-style/code-style.png rename to 1-js/5-code-quality/2-coding-style/code-style.png diff --git a/1-js/4-code-quality/2-coding-style/code-style@2x.png b/1-js/5-code-quality/2-coding-style/code-style@2x.png similarity index 100% rename from 1-js/4-code-quality/2-coding-style/code-style@2x.png rename to 1-js/5-code-quality/2-coding-style/code-style@2x.png diff --git a/1-js/4-code-quality/2-coding-style/figure-bracket-style.png b/1-js/5-code-quality/2-coding-style/figure-bracket-style.png similarity index 100% rename from 1-js/4-code-quality/2-coding-style/figure-bracket-style.png rename to 1-js/5-code-quality/2-coding-style/figure-bracket-style.png diff --git a/1-js/4-code-quality/2-coding-style/figure-bracket-style@2x.png b/1-js/5-code-quality/2-coding-style/figure-bracket-style@2x.png similarity index 100% rename from 1-js/4-code-quality/2-coding-style/figure-bracket-style@2x.png rename to 1-js/5-code-quality/2-coding-style/figure-bracket-style@2x.png diff --git a/1-js/4-code-quality/3-write-unmain-code/article.md b/1-js/5-code-quality/3-write-unmain-code/article.md similarity index 100% rename from 1-js/4-code-quality/3-write-unmain-code/article.md rename to 1-js/5-code-quality/3-write-unmain-code/article.md diff --git a/1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js b/1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js similarity index 100% rename from 1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js rename to 1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js diff --git a/1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js b/1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js similarity index 100% rename from 1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js rename to 1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js diff --git a/1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js b/1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js rename to 1-js/5-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js diff --git a/1-js/4-code-quality/4-testing/1-pow-nan-spec/solution.md b/1-js/5-code-quality/4-testing/1-pow-nan-spec/solution.md similarity index 100% rename from 1-js/4-code-quality/4-testing/1-pow-nan-spec/solution.md rename to 1-js/5-code-quality/4-testing/1-pow-nan-spec/solution.md diff --git a/1-js/4-code-quality/4-testing/1-pow-nan-spec/task.md b/1-js/5-code-quality/4-testing/1-pow-nan-spec/task.md similarity index 100% rename from 1-js/4-code-quality/4-testing/1-pow-nan-spec/task.md rename to 1-js/5-code-quality/4-testing/1-pow-nan-spec/task.md diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/solution.md b/1-js/5-code-quality/4-testing/2-pow-test-0/solution.md similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/solution.md rename to 1-js/5-code-quality/4-testing/2-pow-test-0/solution.md diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/solution.view/index.html b/1-js/5-code-quality/4-testing/2-pow-test-0/solution.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/solution.view/index.html rename to 1-js/5-code-quality/4-testing/2-pow-test-0/solution.view/index.html diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/solution.view/test.js b/1-js/5-code-quality/4-testing/2-pow-test-0/solution.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/solution.view/test.js rename to 1-js/5-code-quality/4-testing/2-pow-test-0/solution.view/test.js diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/source.view/index.html b/1-js/5-code-quality/4-testing/2-pow-test-0/source.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/source.view/index.html rename to 1-js/5-code-quality/4-testing/2-pow-test-0/source.view/index.html diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/source.view/test.js b/1-js/5-code-quality/4-testing/2-pow-test-0/source.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/source.view/test.js rename to 1-js/5-code-quality/4-testing/2-pow-test-0/source.view/test.js diff --git a/1-js/4-code-quality/4-testing/2-pow-test-0/task.md b/1-js/5-code-quality/4-testing/2-pow-test-0/task.md similarity index 100% rename from 1-js/4-code-quality/4-testing/2-pow-test-0/task.md rename to 1-js/5-code-quality/4-testing/2-pow-test-0/task.md diff --git a/1-js/4-code-quality/4-testing/3-pow-test-wrong/solution.md b/1-js/5-code-quality/4-testing/3-pow-test-wrong/solution.md similarity index 100% rename from 1-js/4-code-quality/4-testing/3-pow-test-wrong/solution.md rename to 1-js/5-code-quality/4-testing/3-pow-test-wrong/solution.md diff --git a/1-js/4-code-quality/4-testing/3-pow-test-wrong/task.md b/1-js/5-code-quality/4-testing/3-pow-test-wrong/task.md similarity index 100% rename from 1-js/4-code-quality/4-testing/3-pow-test-wrong/task.md rename to 1-js/5-code-quality/4-testing/3-pow-test-wrong/task.md diff --git a/1-js/4-code-quality/4-testing/article.md b/1-js/5-code-quality/4-testing/article.md similarity index 100% rename from 1-js/4-code-quality/4-testing/article.md rename to 1-js/5-code-quality/4-testing/article.md diff --git a/1-js/4-code-quality/4-testing/beforeafter.view/index.html b/1-js/5-code-quality/4-testing/beforeafter.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/beforeafter.view/index.html rename to 1-js/5-code-quality/4-testing/beforeafter.view/index.html diff --git a/1-js/4-code-quality/4-testing/beforeafter.view/test.js b/1-js/5-code-quality/4-testing/beforeafter.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/beforeafter.view/test.js rename to 1-js/5-code-quality/4-testing/beforeafter.view/test.js diff --git a/1-js/4-code-quality/4-testing/index.html b/1-js/5-code-quality/4-testing/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/index.html rename to 1-js/5-code-quality/4-testing/index.html diff --git a/1-js/4-code-quality/4-testing/pow-1.view/index.html b/1-js/5-code-quality/4-testing/pow-1.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-1.view/index.html rename to 1-js/5-code-quality/4-testing/pow-1.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-1.view/test.js b/1-js/5-code-quality/4-testing/pow-1.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-1.view/test.js rename to 1-js/5-code-quality/4-testing/pow-1.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-2.view/index.html b/1-js/5-code-quality/4-testing/pow-2.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-2.view/index.html rename to 1-js/5-code-quality/4-testing/pow-2.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-2.view/test.js b/1-js/5-code-quality/4-testing/pow-2.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-2.view/test.js rename to 1-js/5-code-quality/4-testing/pow-2.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-3.view/index.html b/1-js/5-code-quality/4-testing/pow-3.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-3.view/index.html rename to 1-js/5-code-quality/4-testing/pow-3.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-3.view/test.js b/1-js/5-code-quality/4-testing/pow-3.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-3.view/test.js rename to 1-js/5-code-quality/4-testing/pow-3.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-4.view/index.html b/1-js/5-code-quality/4-testing/pow-4.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-4.view/index.html rename to 1-js/5-code-quality/4-testing/pow-4.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-4.view/test.js b/1-js/5-code-quality/4-testing/pow-4.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-4.view/test.js rename to 1-js/5-code-quality/4-testing/pow-4.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-full.view/index.html b/1-js/5-code-quality/4-testing/pow-full.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-full.view/index.html rename to 1-js/5-code-quality/4-testing/pow-full.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-full.view/test.js b/1-js/5-code-quality/4-testing/pow-full.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-full.view/test.js rename to 1-js/5-code-quality/4-testing/pow-full.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-min.view/index.html b/1-js/5-code-quality/4-testing/pow-min.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-min.view/index.html rename to 1-js/5-code-quality/4-testing/pow-min.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-min.view/test.js b/1-js/5-code-quality/4-testing/pow-min.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-min.view/test.js rename to 1-js/5-code-quality/4-testing/pow-min.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-nan-assert.view/index.html b/1-js/5-code-quality/4-testing/pow-nan-assert.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-nan-assert.view/index.html rename to 1-js/5-code-quality/4-testing/pow-nan-assert.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-nan-assert.view/test.js b/1-js/5-code-quality/4-testing/pow-nan-assert.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-nan-assert.view/test.js rename to 1-js/5-code-quality/4-testing/pow-nan-assert.view/test.js diff --git a/1-js/4-code-quality/4-testing/pow-nan.view/index.html b/1-js/5-code-quality/4-testing/pow-nan.view/index.html similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-nan.view/index.html rename to 1-js/5-code-quality/4-testing/pow-nan.view/index.html diff --git a/1-js/4-code-quality/4-testing/pow-nan.view/test.js b/1-js/5-code-quality/4-testing/pow-nan.view/test.js similarity index 100% rename from 1-js/4-code-quality/4-testing/pow-nan.view/test.js rename to 1-js/5-code-quality/4-testing/pow-nan.view/test.js diff --git a/1-js/4-code-quality/5-polyfills/article.md b/1-js/5-code-quality/5-polyfills/article.md similarity index 100% rename from 1-js/4-code-quality/5-polyfills/article.md rename to 1-js/5-code-quality/5-polyfills/article.md diff --git a/1-js/4-code-quality/index.md b/1-js/5-code-quality/index.md similarity index 100% rename from 1-js/4-code-quality/index.md rename to 1-js/5-code-quality/index.md diff --git a/1-js/5-data-structures/4-object2/2-is-empty/solution.md b/1-js/5-data-structures/4-object2/2-is-empty/solution.md deleted file mode 100644 index 9b78efa6..00000000 --- a/1-js/5-data-structures/4-object2/2-is-empty/solution.md +++ /dev/null @@ -1,20 +0,0 @@ -There are many ways to solve that. - -Here are two of them: - -```js -function isEmpty(obj) - return Object.keys(obj).length == 0; -} -``` - -```js -function isEmpty(obj) - for(let key in obj) { - return false; - } - return true; -} -``` - -The second one is probably more performant. \ No newline at end of file diff --git a/1-js/5-data-structures/11-date/1-new-date/solution.md b/1-js/6-data-structures/11-date/1-new-date/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/1-new-date/solution.md rename to 1-js/6-data-structures/11-date/1-new-date/solution.md diff --git a/1-js/5-data-structures/11-date/1-new-date/task.md b/1-js/6-data-structures/11-date/1-new-date/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/1-new-date/task.md rename to 1-js/6-data-structures/11-date/1-new-date/task.md diff --git a/1-js/5-data-structures/11-date/2-get-week-day/_js.view/solution.js b/1-js/6-data-structures/11-date/2-get-week-day/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/2-get-week-day/_js.view/solution.js rename to 1-js/6-data-structures/11-date/2-get-week-day/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/2-get-week-day/_js.view/test.js b/1-js/6-data-structures/11-date/2-get-week-day/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/2-get-week-day/_js.view/test.js rename to 1-js/6-data-structures/11-date/2-get-week-day/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/2-get-week-day/solution.md b/1-js/6-data-structures/11-date/2-get-week-day/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/2-get-week-day/solution.md rename to 1-js/6-data-structures/11-date/2-get-week-day/solution.md diff --git a/1-js/5-data-structures/11-date/2-get-week-day/task.md b/1-js/6-data-structures/11-date/2-get-week-day/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/2-get-week-day/task.md rename to 1-js/6-data-structures/11-date/2-get-week-day/task.md diff --git a/1-js/5-data-structures/11-date/3-weekday/_js.view/solution.js b/1-js/6-data-structures/11-date/3-weekday/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/3-weekday/_js.view/solution.js rename to 1-js/6-data-structures/11-date/3-weekday/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/3-weekday/_js.view/test.js b/1-js/6-data-structures/11-date/3-weekday/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/3-weekday/_js.view/test.js rename to 1-js/6-data-structures/11-date/3-weekday/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/3-weekday/solution.md b/1-js/6-data-structures/11-date/3-weekday/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/3-weekday/solution.md rename to 1-js/6-data-structures/11-date/3-weekday/solution.md diff --git a/1-js/5-data-structures/11-date/3-weekday/task.md b/1-js/6-data-structures/11-date/3-weekday/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/3-weekday/task.md rename to 1-js/6-data-structures/11-date/3-weekday/task.md diff --git a/1-js/5-data-structures/11-date/4-get-date-ago/_js.view/solution.js b/1-js/6-data-structures/11-date/4-get-date-ago/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/4-get-date-ago/_js.view/solution.js rename to 1-js/6-data-structures/11-date/4-get-date-ago/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/4-get-date-ago/_js.view/test.js b/1-js/6-data-structures/11-date/4-get-date-ago/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/4-get-date-ago/_js.view/test.js rename to 1-js/6-data-structures/11-date/4-get-date-ago/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/4-get-date-ago/solution.md b/1-js/6-data-structures/11-date/4-get-date-ago/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/4-get-date-ago/solution.md rename to 1-js/6-data-structures/11-date/4-get-date-ago/solution.md diff --git a/1-js/5-data-structures/11-date/4-get-date-ago/task.md b/1-js/6-data-structures/11-date/4-get-date-ago/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/4-get-date-ago/task.md rename to 1-js/6-data-structures/11-date/4-get-date-ago/task.md diff --git a/1-js/5-data-structures/11-date/5-last-day-of-month/_js.view/solution.js b/1-js/6-data-structures/11-date/5-last-day-of-month/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/5-last-day-of-month/_js.view/solution.js rename to 1-js/6-data-structures/11-date/5-last-day-of-month/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/5-last-day-of-month/_js.view/test.js b/1-js/6-data-structures/11-date/5-last-day-of-month/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/5-last-day-of-month/_js.view/test.js rename to 1-js/6-data-structures/11-date/5-last-day-of-month/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/5-last-day-of-month/solution.md b/1-js/6-data-structures/11-date/5-last-day-of-month/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/5-last-day-of-month/solution.md rename to 1-js/6-data-structures/11-date/5-last-day-of-month/solution.md diff --git a/1-js/5-data-structures/11-date/5-last-day-of-month/task.md b/1-js/6-data-structures/11-date/5-last-day-of-month/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/5-last-day-of-month/task.md rename to 1-js/6-data-structures/11-date/5-last-day-of-month/task.md diff --git a/1-js/5-data-structures/11-date/6-get-seconds-today/solution.md b/1-js/6-data-structures/11-date/6-get-seconds-today/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/6-get-seconds-today/solution.md rename to 1-js/6-data-structures/11-date/6-get-seconds-today/solution.md diff --git a/1-js/5-data-structures/11-date/6-get-seconds-today/task.md b/1-js/6-data-structures/11-date/6-get-seconds-today/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/6-get-seconds-today/task.md rename to 1-js/6-data-structures/11-date/6-get-seconds-today/task.md diff --git a/1-js/5-data-structures/11-date/7-get-seconds-to-tomorrow/solution.md b/1-js/6-data-structures/11-date/7-get-seconds-to-tomorrow/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/7-get-seconds-to-tomorrow/solution.md rename to 1-js/6-data-structures/11-date/7-get-seconds-to-tomorrow/solution.md diff --git a/1-js/5-data-structures/11-date/7-get-seconds-to-tomorrow/task.md b/1-js/6-data-structures/11-date/7-get-seconds-to-tomorrow/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/7-get-seconds-to-tomorrow/task.md rename to 1-js/6-data-structures/11-date/7-get-seconds-to-tomorrow/task.md diff --git a/1-js/5-data-structures/11-date/8-format-date-ddmmyy/_js.view/solution.js b/1-js/6-data-structures/11-date/8-format-date-ddmmyy/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/8-format-date-ddmmyy/_js.view/solution.js rename to 1-js/6-data-structures/11-date/8-format-date-ddmmyy/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/8-format-date-ddmmyy/_js.view/test.js b/1-js/6-data-structures/11-date/8-format-date-ddmmyy/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/8-format-date-ddmmyy/_js.view/test.js rename to 1-js/6-data-structures/11-date/8-format-date-ddmmyy/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/8-format-date-ddmmyy/solution.md b/1-js/6-data-structures/11-date/8-format-date-ddmmyy/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/8-format-date-ddmmyy/solution.md rename to 1-js/6-data-structures/11-date/8-format-date-ddmmyy/solution.md diff --git a/1-js/5-data-structures/11-date/8-format-date-ddmmyy/task.md b/1-js/6-data-structures/11-date/8-format-date-ddmmyy/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/8-format-date-ddmmyy/task.md rename to 1-js/6-data-structures/11-date/8-format-date-ddmmyy/task.md diff --git a/1-js/5-data-structures/11-date/9-format-date-relative/_js.view/solution.js b/1-js/6-data-structures/11-date/9-format-date-relative/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/11-date/9-format-date-relative/_js.view/solution.js rename to 1-js/6-data-structures/11-date/9-format-date-relative/_js.view/solution.js diff --git a/1-js/5-data-structures/11-date/9-format-date-relative/_js.view/test.js b/1-js/6-data-structures/11-date/9-format-date-relative/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/11-date/9-format-date-relative/_js.view/test.js rename to 1-js/6-data-structures/11-date/9-format-date-relative/_js.view/test.js diff --git a/1-js/5-data-structures/11-date/9-format-date-relative/solution.md b/1-js/6-data-structures/11-date/9-format-date-relative/solution.md similarity index 100% rename from 1-js/5-data-structures/11-date/9-format-date-relative/solution.md rename to 1-js/6-data-structures/11-date/9-format-date-relative/solution.md diff --git a/1-js/5-data-structures/11-date/9-format-date-relative/task.md b/1-js/6-data-structures/11-date/9-format-date-relative/task.md similarity index 100% rename from 1-js/5-data-structures/11-date/9-format-date-relative/task.md rename to 1-js/6-data-structures/11-date/9-format-date-relative/task.md diff --git a/1-js/5-data-structures/11-date/article.md b/1-js/6-data-structures/11-date/article.md similarity index 100% rename from 1-js/5-data-structures/11-date/article.md rename to 1-js/6-data-structures/11-date/article.md diff --git a/1-js/5-data-structures/2-number/1-sum-interface/solution.md b/1-js/6-data-structures/2-number/1-sum-interface/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/1-sum-interface/solution.md rename to 1-js/6-data-structures/2-number/1-sum-interface/solution.md diff --git a/1-js/5-data-structures/2-number/1-sum-interface/task.md b/1-js/6-data-structures/2-number/1-sum-interface/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/1-sum-interface/task.md rename to 1-js/6-data-structures/2-number/1-sum-interface/task.md diff --git a/1-js/5-data-structures/2-number/2-why-rounded-down/solution.md b/1-js/6-data-structures/2-number/2-why-rounded-down/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/2-why-rounded-down/solution.md rename to 1-js/6-data-structures/2-number/2-why-rounded-down/solution.md diff --git a/1-js/5-data-structures/2-number/2-why-rounded-down/task.md b/1-js/6-data-structures/2-number/2-why-rounded-down/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/2-why-rounded-down/task.md rename to 1-js/6-data-structures/2-number/2-why-rounded-down/task.md diff --git a/1-js/5-data-structures/2-number/3-repeat-until-number/_js.view/solution.js b/1-js/6-data-structures/2-number/3-repeat-until-number/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/2-number/3-repeat-until-number/_js.view/solution.js rename to 1-js/6-data-structures/2-number/3-repeat-until-number/_js.view/solution.js diff --git a/1-js/5-data-structures/2-number/3-repeat-until-number/_js.view/test.js b/1-js/6-data-structures/2-number/3-repeat-until-number/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/2-number/3-repeat-until-number/_js.view/test.js rename to 1-js/6-data-structures/2-number/3-repeat-until-number/_js.view/test.js diff --git a/1-js/5-data-structures/2-number/3-repeat-until-number/solution.md b/1-js/6-data-structures/2-number/3-repeat-until-number/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/3-repeat-until-number/solution.md rename to 1-js/6-data-structures/2-number/3-repeat-until-number/solution.md diff --git a/1-js/5-data-structures/2-number/3-repeat-until-number/task.md b/1-js/6-data-structures/2-number/3-repeat-until-number/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/3-repeat-until-number/task.md rename to 1-js/6-data-structures/2-number/3-repeat-until-number/task.md diff --git a/1-js/5-data-structures/2-number/4-endless-loop-error/solution.md b/1-js/6-data-structures/2-number/4-endless-loop-error/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/4-endless-loop-error/solution.md rename to 1-js/6-data-structures/2-number/4-endless-loop-error/solution.md diff --git a/1-js/5-data-structures/2-number/4-endless-loop-error/task.md b/1-js/6-data-structures/2-number/4-endless-loop-error/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/4-endless-loop-error/task.md rename to 1-js/6-data-structures/2-number/4-endless-loop-error/task.md diff --git a/1-js/5-data-structures/2-number/8-random-min-max/solution.md b/1-js/6-data-structures/2-number/8-random-min-max/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/8-random-min-max/solution.md rename to 1-js/6-data-structures/2-number/8-random-min-max/solution.md diff --git a/1-js/5-data-structures/2-number/8-random-min-max/task.md b/1-js/6-data-structures/2-number/8-random-min-max/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/8-random-min-max/task.md rename to 1-js/6-data-structures/2-number/8-random-min-max/task.md diff --git a/1-js/5-data-structures/2-number/9-random-int-min-max/solution.md b/1-js/6-data-structures/2-number/9-random-int-min-max/solution.md similarity index 100% rename from 1-js/5-data-structures/2-number/9-random-int-min-max/solution.md rename to 1-js/6-data-structures/2-number/9-random-int-min-max/solution.md diff --git a/1-js/5-data-structures/2-number/9-random-int-min-max/task.md b/1-js/6-data-structures/2-number/9-random-int-min-max/task.md similarity index 100% rename from 1-js/5-data-structures/2-number/9-random-int-min-max/task.md rename to 1-js/6-data-structures/2-number/9-random-int-min-max/task.md diff --git a/1-js/5-data-structures/2-number/article.md b/1-js/6-data-structures/2-number/article.md similarity index 100% rename from 1-js/5-data-structures/2-number/article.md rename to 1-js/6-data-structures/2-number/article.md diff --git a/1-js/5-data-structures/3-string/1-ucfirst/_js.view/solution.js b/1-js/6-data-structures/3-string/1-ucfirst/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/3-string/1-ucfirst/_js.view/solution.js rename to 1-js/6-data-structures/3-string/1-ucfirst/_js.view/solution.js diff --git a/1-js/5-data-structures/3-string/1-ucfirst/_js.view/test.js b/1-js/6-data-structures/3-string/1-ucfirst/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/3-string/1-ucfirst/_js.view/test.js rename to 1-js/6-data-structures/3-string/1-ucfirst/_js.view/test.js diff --git a/1-js/5-data-structures/3-string/1-ucfirst/solution.md b/1-js/6-data-structures/3-string/1-ucfirst/solution.md similarity index 100% rename from 1-js/5-data-structures/3-string/1-ucfirst/solution.md rename to 1-js/6-data-structures/3-string/1-ucfirst/solution.md diff --git a/1-js/5-data-structures/3-string/1-ucfirst/task.md b/1-js/6-data-structures/3-string/1-ucfirst/task.md similarity index 100% rename from 1-js/5-data-structures/3-string/1-ucfirst/task.md rename to 1-js/6-data-structures/3-string/1-ucfirst/task.md diff --git a/1-js/5-data-structures/3-string/2-check-spam/_js.view/solution.js b/1-js/6-data-structures/3-string/2-check-spam/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/3-string/2-check-spam/_js.view/solution.js rename to 1-js/6-data-structures/3-string/2-check-spam/_js.view/solution.js diff --git a/1-js/5-data-structures/3-string/2-check-spam/_js.view/test.js b/1-js/6-data-structures/3-string/2-check-spam/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/3-string/2-check-spam/_js.view/test.js rename to 1-js/6-data-structures/3-string/2-check-spam/_js.view/test.js diff --git a/1-js/5-data-structures/3-string/2-check-spam/solution.md b/1-js/6-data-structures/3-string/2-check-spam/solution.md similarity index 100% rename from 1-js/5-data-structures/3-string/2-check-spam/solution.md rename to 1-js/6-data-structures/3-string/2-check-spam/solution.md diff --git a/1-js/5-data-structures/3-string/2-check-spam/task.md b/1-js/6-data-structures/3-string/2-check-spam/task.md similarity index 100% rename from 1-js/5-data-structures/3-string/2-check-spam/task.md rename to 1-js/6-data-structures/3-string/2-check-spam/task.md diff --git a/1-js/5-data-structures/3-string/3-truncate/_js.view/solution.js b/1-js/6-data-structures/3-string/3-truncate/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/3-string/3-truncate/_js.view/solution.js rename to 1-js/6-data-structures/3-string/3-truncate/_js.view/solution.js diff --git a/1-js/5-data-structures/3-string/3-truncate/_js.view/test.js b/1-js/6-data-structures/3-string/3-truncate/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/3-string/3-truncate/_js.view/test.js rename to 1-js/6-data-structures/3-string/3-truncate/_js.view/test.js diff --git a/1-js/5-data-structures/3-string/3-truncate/solution.md b/1-js/6-data-structures/3-string/3-truncate/solution.md similarity index 100% rename from 1-js/5-data-structures/3-string/3-truncate/solution.md rename to 1-js/6-data-structures/3-string/3-truncate/solution.md diff --git a/1-js/5-data-structures/3-string/3-truncate/task.md b/1-js/6-data-structures/3-string/3-truncate/task.md similarity index 100% rename from 1-js/5-data-structures/3-string/3-truncate/task.md rename to 1-js/6-data-structures/3-string/3-truncate/task.md diff --git a/1-js/5-data-structures/3-string/4-extract-currency/_js.view/solution.js b/1-js/6-data-structures/3-string/4-extract-currency/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/3-string/4-extract-currency/_js.view/solution.js rename to 1-js/6-data-structures/3-string/4-extract-currency/_js.view/solution.js diff --git a/1-js/5-data-structures/3-string/4-extract-currency/_js.view/test.js b/1-js/6-data-structures/3-string/4-extract-currency/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/3-string/4-extract-currency/_js.view/test.js rename to 1-js/6-data-structures/3-string/4-extract-currency/_js.view/test.js diff --git a/1-js/5-data-structures/3-string/4-extract-currency/solution.md b/1-js/6-data-structures/3-string/4-extract-currency/solution.md similarity index 100% rename from 1-js/5-data-structures/3-string/4-extract-currency/solution.md rename to 1-js/6-data-structures/3-string/4-extract-currency/solution.md diff --git a/1-js/5-data-structures/3-string/4-extract-currency/task.md b/1-js/6-data-structures/3-string/4-extract-currency/task.md similarity index 100% rename from 1-js/5-data-structures/3-string/4-extract-currency/task.md rename to 1-js/6-data-structures/3-string/4-extract-currency/task.md diff --git a/1-js/5-data-structures/3-string/article.md b/1-js/6-data-structures/3-string/article.md similarity index 100% rename from 1-js/5-data-structures/3-string/article.md rename to 1-js/6-data-structures/3-string/article.md diff --git a/1-js/5-data-structures/4-object2/article.md b/1-js/6-data-structures/4-object2/article.md similarity index 100% rename from 1-js/5-data-structures/4-object2/article.md rename to 1-js/6-data-structures/4-object2/article.md diff --git a/1-js/5-data-structures/7-array-methods/1-camelcase/_js.view/solution.js b/1-js/6-data-structures/7-array-methods/1-camelcase/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/1-camelcase/_js.view/solution.js rename to 1-js/6-data-structures/7-array-methods/1-camelcase/_js.view/solution.js diff --git a/1-js/5-data-structures/7-array-methods/1-camelcase/_js.view/test.js b/1-js/6-data-structures/7-array-methods/1-camelcase/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/1-camelcase/_js.view/test.js rename to 1-js/6-data-structures/7-array-methods/1-camelcase/_js.view/test.js diff --git a/1-js/5-data-structures/7-array-methods/1-camelcase/solution.md b/1-js/6-data-structures/7-array-methods/1-camelcase/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/1-camelcase/solution.md rename to 1-js/6-data-structures/7-array-methods/1-camelcase/solution.md diff --git a/1-js/5-data-structures/7-array-methods/1-camelcase/task.md b/1-js/6-data-structures/7-array-methods/1-camelcase/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/1-camelcase/task.md rename to 1-js/6-data-structures/7-array-methods/1-camelcase/task.md diff --git a/1-js/5-data-structures/7-array-methods/11-array-unique/_js.view/solution.js b/1-js/6-data-structures/7-array-methods/11-array-unique/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/11-array-unique/_js.view/solution.js rename to 1-js/6-data-structures/7-array-methods/11-array-unique/_js.view/solution.js diff --git a/1-js/5-data-structures/7-array-methods/11-array-unique/_js.view/test.js b/1-js/6-data-structures/7-array-methods/11-array-unique/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/11-array-unique/_js.view/test.js rename to 1-js/6-data-structures/7-array-methods/11-array-unique/_js.view/test.js diff --git a/1-js/5-data-structures/7-array-methods/11-array-unique/solution.md b/1-js/6-data-structures/7-array-methods/11-array-unique/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/11-array-unique/solution.md rename to 1-js/6-data-structures/7-array-methods/11-array-unique/solution.md diff --git a/1-js/5-data-structures/7-array-methods/11-array-unique/task.md b/1-js/6-data-structures/7-array-methods/11-array-unique/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/11-array-unique/task.md rename to 1-js/6-data-structures/7-array-methods/11-array-unique/task.md diff --git a/1-js/5-data-structures/7-array-methods/2-filter-range/_js.view/solution.js b/1-js/6-data-structures/7-array-methods/2-filter-range/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/2-filter-range/_js.view/solution.js rename to 1-js/6-data-structures/7-array-methods/2-filter-range/_js.view/solution.js diff --git a/1-js/5-data-structures/7-array-methods/2-filter-range/_js.view/test.js b/1-js/6-data-structures/7-array-methods/2-filter-range/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/2-filter-range/_js.view/test.js rename to 1-js/6-data-structures/7-array-methods/2-filter-range/_js.view/test.js diff --git a/1-js/5-data-structures/7-array-methods/2-filter-range/solution.md b/1-js/6-data-structures/7-array-methods/2-filter-range/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/2-filter-range/solution.md rename to 1-js/6-data-structures/7-array-methods/2-filter-range/solution.md diff --git a/1-js/5-data-structures/7-array-methods/2-filter-range/task.md b/1-js/6-data-structures/7-array-methods/2-filter-range/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/2-filter-range/task.md rename to 1-js/6-data-structures/7-array-methods/2-filter-range/task.md diff --git a/1-js/5-data-structures/7-array-methods/3-filter-range-in-place/_js.view/solution.js b/1-js/6-data-structures/7-array-methods/3-filter-range-in-place/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/3-filter-range-in-place/_js.view/solution.js rename to 1-js/6-data-structures/7-array-methods/3-filter-range-in-place/_js.view/solution.js diff --git a/1-js/5-data-structures/7-array-methods/3-filter-range-in-place/_js.view/test.js b/1-js/6-data-structures/7-array-methods/3-filter-range-in-place/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/7-array-methods/3-filter-range-in-place/_js.view/test.js rename to 1-js/6-data-structures/7-array-methods/3-filter-range-in-place/_js.view/test.js diff --git a/1-js/5-data-structures/7-array-methods/3-filter-range-in-place/solution.md b/1-js/6-data-structures/7-array-methods/3-filter-range-in-place/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/3-filter-range-in-place/solution.md rename to 1-js/6-data-structures/7-array-methods/3-filter-range-in-place/solution.md diff --git a/1-js/5-data-structures/7-array-methods/3-filter-range-in-place/task.md b/1-js/6-data-structures/7-array-methods/3-filter-range-in-place/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/3-filter-range-in-place/task.md rename to 1-js/6-data-structures/7-array-methods/3-filter-range-in-place/task.md diff --git a/1-js/5-data-structures/7-array-methods/4-sort-back/solution.md b/1-js/6-data-structures/7-array-methods/4-sort-back/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/4-sort-back/solution.md rename to 1-js/6-data-structures/7-array-methods/4-sort-back/solution.md diff --git a/1-js/5-data-structures/7-array-methods/4-sort-back/task.md b/1-js/6-data-structures/7-array-methods/4-sort-back/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/4-sort-back/task.md rename to 1-js/6-data-structures/7-array-methods/4-sort-back/task.md diff --git a/1-js/5-data-structures/7-array-methods/5-copy-sort-array/solution.md b/1-js/6-data-structures/7-array-methods/5-copy-sort-array/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/5-copy-sort-array/solution.md rename to 1-js/6-data-structures/7-array-methods/5-copy-sort-array/solution.md diff --git a/1-js/5-data-structures/7-array-methods/5-copy-sort-array/task.md b/1-js/6-data-structures/7-array-methods/5-copy-sort-array/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/5-copy-sort-array/task.md rename to 1-js/6-data-structures/7-array-methods/5-copy-sort-array/task.md diff --git a/1-js/5-data-structures/7-array-methods/6-array-get-names/solution.md b/1-js/6-data-structures/7-array-methods/6-array-get-names/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/6-array-get-names/solution.md rename to 1-js/6-data-structures/7-array-methods/6-array-get-names/solution.md diff --git a/1-js/5-data-structures/7-array-methods/6-array-get-names/task.md b/1-js/6-data-structures/7-array-methods/6-array-get-names/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/6-array-get-names/task.md rename to 1-js/6-data-structures/7-array-methods/6-array-get-names/task.md diff --git a/1-js/5-data-structures/7-array-methods/7-sort-objects/solution.md b/1-js/6-data-structures/7-array-methods/7-sort-objects/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/7-sort-objects/solution.md rename to 1-js/6-data-structures/7-array-methods/7-sort-objects/solution.md diff --git a/1-js/5-data-structures/7-array-methods/7-sort-objects/task.md b/1-js/6-data-structures/7-array-methods/7-sort-objects/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/7-sort-objects/task.md rename to 1-js/6-data-structures/7-array-methods/7-sort-objects/task.md diff --git a/1-js/5-data-structures/7-array-methods/8-average-age/solution.md b/1-js/6-data-structures/7-array-methods/8-average-age/solution.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/8-average-age/solution.md rename to 1-js/6-data-structures/7-array-methods/8-average-age/solution.md diff --git a/1-js/5-data-structures/7-array-methods/8-average-age/task.md b/1-js/6-data-structures/7-array-methods/8-average-age/task.md similarity index 100% rename from 1-js/5-data-structures/7-array-methods/8-average-age/task.md rename to 1-js/6-data-structures/7-array-methods/8-average-age/task.md diff --git a/1-js/5-data-structures/7-array-methods/article.md b/1-js/6-data-structures/7-array-methods/article.md similarity index 96% rename from 1-js/5-data-structures/7-array-methods/article.md rename to 1-js/6-data-structures/7-array-methods/article.md index e9b21ac5..88e4a7a1 100644 --- a/1-js/5-data-structures/7-array-methods/article.md +++ b/1-js/6-data-structures/7-array-methods/article.md @@ -447,6 +447,27 @@ But such use requires an extreme care. If the array is empty, then `reduce` call The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same, but goes from right to left. + +## Array.isArray + +Arrays do not form a separate language type. They are based on objects. + +So `typeof` does not help to distinguish a plain object from an array: + +```js run +alert(typeof {}); // object +alert(typeof []); // same +``` + +There's a special method for that [Array.isArray(value)](mdn:js/Array/isArray) that returns `true` if the `value` is an array, and `false` otherwise. + +```js run +alert(Array.isArray({})); // false + +alert(Array.isArray([])); // true +``` + + ## Other methods We covered the most useful methods. But there are other too, for instance: @@ -467,16 +488,6 @@ We covered the most useful methods. But there are other too, for instance: The function `fn` is called on each element of the array similar to `map`. If any/all results are `true`, returns `true`, otherwise `false`. -- [Array.isArray(value)](mdn:js/Array/isArray) checks if the `value` is an array. - - As we've seen in the chapter , the `typeof` operator cannot differ an array from a plain object: - - ```js run - alert( typeof {} ); // object - alert( typeof [] ); // object - ``` - - The call `Array.isArray(value)` helps. It returns `true` if `value` is an array, otherwise `false`. These and other methods are also listed in the [manual](mdn:js/Array). diff --git a/1-js/5-data-structures/7-array-methods/reduce.png b/1-js/6-data-structures/7-array-methods/reduce.png similarity index 100% rename from 1-js/5-data-structures/7-array-methods/reduce.png rename to 1-js/6-data-structures/7-array-methods/reduce.png diff --git a/1-js/5-data-structures/7-array-methods/reduce@2x.png b/1-js/6-data-structures/7-array-methods/reduce@2x.png similarity index 100% rename from 1-js/5-data-structures/7-array-methods/reduce@2x.png rename to 1-js/6-data-structures/7-array-methods/reduce@2x.png diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/solution.js b/1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/solution.js similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/solution.js rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/solution.js diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/test.js b/1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/test.js similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/test.js rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/_js.view/test.js diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/solution.md b/1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/solution.md similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/solution.md rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/solution.md diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/task.md b/1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/task.md similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/task.md rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/1-filter-anagrams/task.md diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/2-recipients-set/solution.md b/1-js/6-data-structures/9-map-set-weakmap-weakset/2-recipients-set/solution.md similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/2-recipients-set/solution.md rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/2-recipients-set/solution.md diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/2-recipients-set/task.md b/1-js/6-data-structures/9-map-set-weakmap-weakset/2-recipients-set/task.md similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/2-recipients-set/task.md rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/2-recipients-set/task.md diff --git a/1-js/5-data-structures/9-map-set-weakmap-weakset/article.md b/1-js/6-data-structures/9-map-set-weakmap-weakset/article.md similarity index 100% rename from 1-js/5-data-structures/9-map-set-weakmap-weakset/article.md rename to 1-js/6-data-structures/9-map-set-weakmap-weakset/article.md diff --git a/1-js/5-data-structures/index.md b/1-js/6-data-structures/index.md similarity index 100% rename from 1-js/5-data-structures/index.md rename to 1-js/6-data-structures/index.md diff --git a/1-js/6-deeper/1-recursion/linked-list-0.png b/1-js/6-deeper/1-recursion/linked-list-0.png deleted file mode 100644 index 90be753a..00000000 Binary files a/1-js/6-deeper/1-recursion/linked-list-0.png and /dev/null differ diff --git a/1-js/6-deeper/1-recursion/linked-list-0@2x.png b/1-js/6-deeper/1-recursion/linked-list-0@2x.png deleted file mode 100644 index 26da8c0f..00000000 Binary files a/1-js/6-deeper/1-recursion/linked-list-0@2x.png and /dev/null differ diff --git a/1-js/6-deeper/1-recursion/linked-list-remove-1.png b/1-js/6-deeper/1-recursion/linked-list-remove-1.png deleted file mode 100644 index 7cc083c9..00000000 Binary files a/1-js/6-deeper/1-recursion/linked-list-remove-1.png and /dev/null differ diff --git a/1-js/6-deeper/1-recursion/linked-list-remove-1@2x.png b/1-js/6-deeper/1-recursion/linked-list-remove-1@2x.png deleted file mode 100644 index f9200ff2..00000000 Binary files a/1-js/6-deeper/1-recursion/linked-list-remove-1@2x.png and /dev/null differ diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5.png b/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5.png deleted file mode 100644 index 527c4157..00000000 Binary files a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5.png and /dev/null differ diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5@2x.png b/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5@2x.png deleted file mode 100644 index 035dfd31..00000000 Binary files a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-5@2x.png and /dev/null differ diff --git a/1-js/6-deeper/1-recursion/1-sum-to/solution.md b/1-js/7-deeper/1-recursion/1-sum-to/solution.md similarity index 100% rename from 1-js/6-deeper/1-recursion/1-sum-to/solution.md rename to 1-js/7-deeper/1-recursion/1-sum-to/solution.md diff --git a/1-js/6-deeper/1-recursion/1-sum-to/task.md b/1-js/7-deeper/1-recursion/1-sum-to/task.md similarity index 100% rename from 1-js/6-deeper/1-recursion/1-sum-to/task.md rename to 1-js/7-deeper/1-recursion/1-sum-to/task.md diff --git a/1-js/6-deeper/1-recursion/2-factorial/solution.md b/1-js/7-deeper/1-recursion/2-factorial/solution.md similarity index 100% rename from 1-js/6-deeper/1-recursion/2-factorial/solution.md rename to 1-js/7-deeper/1-recursion/2-factorial/solution.md diff --git a/1-js/6-deeper/1-recursion/2-factorial/task.md b/1-js/7-deeper/1-recursion/2-factorial/task.md similarity index 100% rename from 1-js/6-deeper/1-recursion/2-factorial/task.md rename to 1-js/7-deeper/1-recursion/2-factorial/task.md diff --git a/1-js/6-deeper/1-recursion/3-fibonacci-numbers/solution.md b/1-js/7-deeper/1-recursion/3-fibonacci-numbers/solution.md similarity index 100% rename from 1-js/6-deeper/1-recursion/3-fibonacci-numbers/solution.md rename to 1-js/7-deeper/1-recursion/3-fibonacci-numbers/solution.md diff --git a/1-js/6-deeper/1-recursion/3-fibonacci-numbers/task.md b/1-js/7-deeper/1-recursion/3-fibonacci-numbers/task.md similarity index 100% rename from 1-js/6-deeper/1-recursion/3-fibonacci-numbers/task.md rename to 1-js/7-deeper/1-recursion/3-fibonacci-numbers/task.md diff --git a/1-js/6-deeper/1-recursion/9-output-single-linked-list/solution.md b/1-js/7-deeper/1-recursion/9-output-single-linked-list/solution.md similarity index 100% rename from 1-js/6-deeper/1-recursion/9-output-single-linked-list/solution.md rename to 1-js/7-deeper/1-recursion/9-output-single-linked-list/solution.md diff --git a/1-js/6-deeper/1-recursion/9-output-single-linked-list/task.md b/1-js/7-deeper/1-recursion/9-output-single-linked-list/task.md similarity index 100% rename from 1-js/6-deeper/1-recursion/9-output-single-linked-list/task.md rename to 1-js/7-deeper/1-recursion/9-output-single-linked-list/task.md diff --git a/1-js/6-deeper/1-recursion/article.md b/1-js/7-deeper/1-recursion/article.md similarity index 70% rename from 1-js/6-deeper/1-recursion/article.md rename to 1-js/7-deeper/1-recursion/article.md index e001fc17..74a1a58c 100644 --- a/1-js/6-deeper/1-recursion/article.md +++ b/1-js/7-deeper/1-recursion/article.md @@ -2,11 +2,9 @@ A function solves a task. In the process it can call many other functions. A partial case of this is when a function calls *itself*. -That's called *a recursion*. +That's called *recursion*. -Recursion is useful in situations when a task can be naturally split into several tasks of the same kind, but simpler. Or when a task can be simplified into an easy action plus a simpler variant of the same task. - -Soon we'll see examples. +Recursion is useful in situations when a task can be naturally split into several tasks of the same kind, but simpler. Or when a task can be simplified into an easy action plus a simpler variant of the same task. Or, as we'll see soon, to deal with certain data structures. Recursion is a common programming topic, not specific to Javascript. If you developed in other languages or studied algorithms, then you probably already know what's this. @@ -14,9 +12,9 @@ The chapter is mostly meant for those who are unfamiliar with the topic and want [cut] -## Recursive thinking +## Two ways of thinking -For something simple to start with -- let's consider a task of raising `x` into a natural power of `n`. In other words, we need `x` multiplied by itself `n` times. +For something simple to start with -- let's consider a task of raising `x` to a natural power of `n`. In other words, we need `x` multiplied by itself `n` times. There are two ways to solve it. @@ -37,7 +35,7 @@ There are two ways to solve it. alert( pow(2, 3) ); // 8 ``` -2. Recursive thinking -- simplify the task: +2. Recursive thinking -- simplify the task and call self: ```js run function pow(x, n) { @@ -51,7 +49,7 @@ There are two ways to solve it. alert( pow(2, 3) ); // 8 ``` -The recursive variant represents the function as a simple action plus a simplified task: +The recursive variant has two branches: ```js if n==1 = x @@ -61,14 +59,14 @@ pow(x, n) = else ``` - -Here we have two branches. - 1. The `n==1` is the trivial variant. It is called *the base* of recursion, because it immediately produces the obvious result: `pow(x, 1)` equals `x`. 2. Otherwise, we can represent `pow(x, n)` as `x * pow(x, n-1)`. In maths, one would write xn = x * xn-1. This is called *a recursive step*, because we transform the task into a simpler action (multiplication by `x`) and a simpler call of the same task (`pow` with lower `n`). Next steps simplify it further and further untill `n` reaches `1`. We can also say that `pow` *recursively calls itself* till `n == 1`. +![recursive diagram of pow](recursion-pow.png) + + For example, to calculate `pow(2, 4)` the recursive variant does these steps: 1. `pow(2, 4) = 2 * pow(2, 3)` @@ -76,10 +74,12 @@ For example, to calculate `pow(2, 4)` the recursive variant does these steps: 3. `pow(2, 2) = 2 * pow(2, 1)` 4. `pow(2, 1) = 2` -````smart header="Recursion is usually shorter" -A recursive solution is usually shorter. +So, the recursion can be used to reduce a function call to a simpler one, and then -- to even more simpler, and so on, until the result becomes obvious. -Here we can write the same using the ternary `?` operator instead of `if` to make it even more terse and still very readable: +````smart header="Recursion is usually shorter" +A recursive solution is usually shorter than iterative. + +Here we can write the same using the ternary `?` operator instead of `if` to make it `pow(x, n)` more terse and still very readable: ```js run function pow(x, n) { @@ -88,24 +88,27 @@ function pow(x, n) { ``` ```` -So, the recursion can be used when a function call can be reduced to a simpler call, and then -- to even more simpler, and so on, until the result becomes obvious. - The maximal number of nested calls (including the first one) is called *recursion depth*. In our case, it there will be exactly `n`. The maximal recursion depth is limited by Javascript engine. We can make sure about 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help to alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases. -That limits the application of recursion, but it still remains very wide. There are many tasks where a recursive way of thinking gives simpler code, easier to maintain. +That limits the application of recursion, but it still remains very wide. There are many tasks where recursive way of thinking gives simpler code, easier to maintain. ## The execution stack Now let's examine how recursive calls work. For that we'll look under the hood of functions, how they work. + The information about a function run is stored in its *execution context*. -The [execution context](https://tc39.github.io/ecma262/#sec-execution-contexts) is an internal data structure that contains details about where the execution flow is now, current variables, the value of `this` (we don't use it here) and few other internal details. +The [execution context](https://tc39.github.io/ecma262/#sec-execution-contexts) is an internal data structure that contains details about the execution: where the control flow is now, current variables, the value of `this` (we don't use it here) and few other internal details. + +Execution contexts together form an *execution stack*. When a subcall happens, current execution context is pushed on top of the stack, and when it finishes -- popped of it and resumed. + +Let's see what happens during the `pow(2, 3)` call. ### pow(2, 3) -For instance, for the beginning of the call `pow(2, 3)` the execution context will store variables: `x = 2, n = 3`, the execution flow is at line `1` of the function. +In the beginning of the call `pow(2, 3)` the execution context will store variables: `x = 2, n = 3`, the execution flow is at line `1` of the function. We can sketch it as: @@ -142,7 +145,7 @@ The variables are same, but the line changes, so the context is now: -To calculate `x * pow(x, n-1)`, we need to run `pow` witn new arguments. +To calculate `x*pow(x, n-1)`, we need to make a subcall of `pow` with new arguments. ### pow(2, 2) @@ -150,11 +153,11 @@ To do a nested call, Javascript remembers the current execution context in the * Here we call the same function `pow`, but it absolutely doesn't matter. The process is the same for all functions: -1. The current context is "laid away" on top of the stack. +1. The current context is "pushed away" on top of the stack. 2. The new context is created for the subcall. 3. When the subcall is finished -- the previous context is popped from the stack, and its execution continues. -The context stack as a list where the current execution context is always on-top, and previous remembered contexts are below: +Here's the context stack when we entered the subcall `pow(2, 2)`:
  • @@ -167,10 +170,9 @@ The context stack as a list where the current execution context is always on-top
-Here, the new current execution context is also made bold for clarity. - -Note that the context of the previous call not only includes the variables, but also the place in the code, so when the new call finishes -- it would be easy to resume. We use a word "line" in the illustrations for that, but of course in fact it's more precise. +The new current execution context is on top (and bold), and previous remembered contexts are below. +When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped. Here in the picture we use the word "line", but of course it's more precise. ### pow(2, 1) @@ -305,22 +307,24 @@ In other words, a company has departments. - A department may have an array of staff. For instance, `sales` department has 2 employees: John and Alice. - Or a department may split into subdepartments, like `development` has two branches: `sites` and `internals`. Each of them has the own staff. -- It is also possible that when a subdepartment grows, it divides further. For instance, the `sites` department in the future may be split into teams for `siteA` and `siteB`. And they, potentially, can split even more. That's not on the picture, just something to have in mind. +- It is also possible that when a subdepartment grows, it divides into subsubdepartments (or teams). -Now let's say we want to get the sum of all salaries. How can we do that? + For instance, the `sites` department in the future may be split into teams for `siteA` and `siteB`. And they, potentially, can split even more. That's not on the picture, just something to have in mind. -An iterative approach is not easy, because the structure is not simple. The first idea may be to make a `for..in` loop over `company` with nested subloop over 1st level departments. But then we need more nested subloops to iterate over the staff in 2nd level departments like `sites`. ...And then another subloop inside those for 3rd level departments that might appear in the future? Should we stop on level 3 or make 4 levels of loops? At this point the code becomes not just nonuniversal, but also rather ugly (sure, every programmer tried it). +Now let's say we want a function to get the sum of all salaries. How can we do that? -Let's try recursion. We need to write a function that gets an arbitrary department and then either returns the result immediately or simplifies the task. +An iterative approach is not easy, because the structure is not simple. The first idea may be to make a `for` loop over `company` with nested subloop over 1st level departments. But then we need more nested subloops to iterate over the staff in 2nd level departments like `sites`. ...And then another subloop inside those for 3rd level departments that might appear in the future? Should we stop on level 3 or make 4 levels of loops? If we put 3-4 nested subloops in the code to traverse a single object, it becomes rather ugly. + +Let's try recursion. As we can see, when our function gets a department to sum, there are two possible cases: -1. Either it's a "simple" department with an array of people -- then we can sum the salaries in a simple loop. -2. Or it's an object with `N` subdepartments -- then we can make `N` recursive calls to get the sum for each of the subdeps and combine the results. +1. Either it's a "simple" department with an *array of people* -- then we can sum the salaries in a simple loop. +2. Or it's *an object with `N` subdepartments* -- then we can make `N` recursive calls to get the sum for each of the subdeps and combine the results. The (1) is the base of recursion, the trivial case. -The (2) is a recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). +The (2) is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1). The algorithm is probably even easier to read from the code: @@ -342,7 +346,7 @@ function sumSalaries(department) { } else { // case (2) let sum = 0; for(let subdep of Object.values(department)) { - sum += sumSalaries(subdep); // recursively call for subdeps, sum the results + sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results } return sum; } @@ -354,11 +358,18 @@ alert(sumSalaries(company)); // 6700 The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting. -Note that it uses smart features that we've covered before: +Here's the diagram of calls: + +![recursive salaries](recursive-salaries.png) + +We can easily see the principle: for an object `{...}` subcalls are made, while arrays `[...]` are the "leaves" of the recursion tree, they give immediate result. + +Note that the code uses smart features that we've covered before: - Method `arr.reduce` explained in the chapter to get the sum of the array. - Loop `for(val of Object.values(obj))` to iterate over object values: `Object.values` returns an array of them. + ## Recursive structures A recursive (recursively-defined) data structure is a structure that replicates itself in parts. @@ -369,21 +380,20 @@ A company *department* is: - Either an array of people. - Or an object with *departments*. -A more familiar example for web-developers would be an HTML or XML document. +For web-developers there are much better known examples: HTML and XML documents. -In the document, an *HTML-tag* may contain a list of: +In the HTML document, an *HTML-tag* may contain a list of: - Text pieces. - HTML-comments. - Other *HTML-tags* (that in turn may contain text pieces/comments or other tags etc). That's once again a recursive definition. -There exist other structures as well, and we can create them by ourselves where convenient. +For better understanding, we'll cover one more recursive structure named "Linked list" that might be a better alternative for arrays in some cases. ### Linked list - -For instance, we want to store an ordered list of objects. +Imagine, we want to store an ordered list of objects. The natural choice would be an array: @@ -391,17 +401,15 @@ The natural choice would be an array: let arr = [obj1, obj2, obj3]; ``` -...But there's a problem with arrays. The "delete element" and "insert element" operations are expensive. For instance, `arr.unshift(obj)` operation has to renumber all elements to make room for a new `obj`, and if the array is big, it takes time. +...But there's a problem with arrays. The "delete element" and "insert element" operations are expensive. For instance, `arr.unshift(obj)` operation has to renumber all elements to make room for a new `obj`, and if the array is big, it takes time. Same with `arr.shift()`. -Actually, the only structural modifications that do not require mass-renumbering are those that operate with the end of array: `arr.push/pop`. - -So, an array has drawbacks. +The only structural modifications that do not require mass-renumbering are those that operate with the end of array: `arr.push/pop`. So an array can be quite slow for big queues. Alternatively, if we really need fast insertion/deletion, we can choose another data structure called a [linked list](https://en.wikipedia.org/wiki/Linked_list). The *linked list element* is recursively defined as an object with: - `value`. -- `next` property referencing the next *list element* if exists or is `null` otherwise. +- `next` property referencing the next *linked list element* or `null` if that's the end. For instance: @@ -434,9 +442,9 @@ list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; ``` -Here we have multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain. +Here we can even more clearer see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element. -The data structure is interesting, because it can be easily split into multiple parts. For instance: +The list can be easily split into multiple parts and later joined back: ```js let secondList = list.next.next; @@ -445,7 +453,7 @@ list.next.next = null; ![linked list split](linked-list-split.png) -Later lists can be easily joined by changing `next` back: +To join: ```js list.next.next = secondList; @@ -453,7 +461,7 @@ list.next.next = secondList; And surely we can insert or remove items in any place. -For instance, to prepend a new value to the `list`: +For instance, to prepend a new value, we need to update the head of the list: ```js let list = { value: 1 }; @@ -461,8 +469,10 @@ list.next = { value: 2 }; list.next.next = { value: 3 }; list.next.next.next = { value: 4 }; -// now list starts with value:0 -list = { value: 0, next: list }; +*!* +// prepend the new value to the list +list = { value: "new item", next: list }; +*/!* ``` ![linked list](linked-list-0.png) @@ -475,17 +485,15 @@ list.next = list.next.next; ![linked list](linked-list-remove-1.png) -Now `list.next` jumps over to value `2`. The value `1` is excluded from the chain. If it's not stored anywhere else, it will be automatically removed from the memory. +We made `list.next` jump over `1` to value `2`. The value `1` is now excluded from the chain. If it's not stored anywhere else, it will be automatically removed from the memory. -We now don't have mass-renumbering and can easily rearrange elements. +Unlike arrays, there's no mass-renumbering, we can easily rearrange elements. But it's a trade-off, because: -- We can't easily access an element by a number. We need to start from the first one `list` and go `next` `N` times to get the Nth element. -- To insert or remove an element from the structure, we must first get the reference to its previous neighbour, and then alter its `next`. - -...But sometimes these drawbacks do not matter. For instance, when we need a [deque](https://en.wikipedia.org/wiki/Double-ended_queue): the ordered structure that must allow very fast adding/removing elements from both ends. For that we can add another variable named `tail` to track the last element of the list (and update it when adding/removing elements from the end). - +- We can't easily access an element by its number in the list. We need to start from the first one `list` and go `next` `N` times to get the Nth element. +- To insert or remove an element from the structure, we must first get the reference to its previous neighbour, and then alter its `next`. +Although, sometimes these drawbacks do not matter. For instance, when we need a queue or even a [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- the ordered structure that must allow very fast adding/removing elements from both ends. For that we can add another variable named `tail` to track the last element of the list (and update it when adding/removing elements from the end). For large sets of elements the speed difference versus arrays will be huge. ## Summary diff --git a/1-js/6-deeper/1-recursion/head.html b/1-js/7-deeper/1-recursion/head.html similarity index 100% rename from 1-js/6-deeper/1-recursion/head.html rename to 1-js/7-deeper/1-recursion/head.html diff --git a/1-js/7-deeper/1-recursion/linked-list-0.png b/1-js/7-deeper/1-recursion/linked-list-0.png new file mode 100644 index 00000000..000a80da Binary files /dev/null and b/1-js/7-deeper/1-recursion/linked-list-0.png differ diff --git a/1-js/7-deeper/1-recursion/linked-list-0@2x.png b/1-js/7-deeper/1-recursion/linked-list-0@2x.png new file mode 100644 index 00000000..5a236869 Binary files /dev/null and b/1-js/7-deeper/1-recursion/linked-list-0@2x.png differ diff --git a/1-js/7-deeper/1-recursion/linked-list-remove-1.png b/1-js/7-deeper/1-recursion/linked-list-remove-1.png new file mode 100644 index 00000000..477989ad Binary files /dev/null and b/1-js/7-deeper/1-recursion/linked-list-remove-1.png differ diff --git a/1-js/7-deeper/1-recursion/linked-list-remove-1@2x.png b/1-js/7-deeper/1-recursion/linked-list-remove-1@2x.png new file mode 100644 index 00000000..41de7661 Binary files /dev/null and b/1-js/7-deeper/1-recursion/linked-list-remove-1@2x.png differ diff --git a/1-js/6-deeper/1-recursion/linked-list-split.png b/1-js/7-deeper/1-recursion/linked-list-split.png similarity index 100% rename from 1-js/6-deeper/1-recursion/linked-list-split.png rename to 1-js/7-deeper/1-recursion/linked-list-split.png diff --git a/1-js/6-deeper/1-recursion/linked-list-split@2x.png b/1-js/7-deeper/1-recursion/linked-list-split@2x.png similarity index 100% rename from 1-js/6-deeper/1-recursion/linked-list-split@2x.png rename to 1-js/7-deeper/1-recursion/linked-list-split@2x.png diff --git a/1-js/6-deeper/1-recursion/linked-list.png b/1-js/7-deeper/1-recursion/linked-list.png similarity index 100% rename from 1-js/6-deeper/1-recursion/linked-list.png rename to 1-js/7-deeper/1-recursion/linked-list.png diff --git a/1-js/6-deeper/1-recursion/linked-list@2x.png b/1-js/7-deeper/1-recursion/linked-list@2x.png similarity index 100% rename from 1-js/6-deeper/1-recursion/linked-list@2x.png rename to 1-js/7-deeper/1-recursion/linked-list@2x.png diff --git a/1-js/7-deeper/1-recursion/recursion-pow.png b/1-js/7-deeper/1-recursion/recursion-pow.png new file mode 100644 index 00000000..30577f89 Binary files /dev/null and b/1-js/7-deeper/1-recursion/recursion-pow.png differ diff --git a/1-js/7-deeper/1-recursion/recursion-pow@2x.png b/1-js/7-deeper/1-recursion/recursion-pow@2x.png new file mode 100644 index 00000000..c1997342 Binary files /dev/null and b/1-js/7-deeper/1-recursion/recursion-pow@2x.png differ diff --git a/1-js/7-deeper/1-recursion/recursive-salaries.png b/1-js/7-deeper/1-recursion/recursive-salaries.png new file mode 100644 index 00000000..2b901540 Binary files /dev/null and b/1-js/7-deeper/1-recursion/recursive-salaries.png differ diff --git a/1-js/7-deeper/1-recursion/recursive-salaries@2x.png b/1-js/7-deeper/1-recursion/recursive-salaries@2x.png new file mode 100644 index 00000000..261ab144 Binary files /dev/null and b/1-js/7-deeper/1-recursion/recursive-salaries@2x.png differ diff --git a/1-js/6-deeper/2-closure/1-counter-independent/solution.md b/1-js/7-deeper/2-closure/1-counter-independent/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/1-counter-independent/solution.md rename to 1-js/7-deeper/2-closure/1-counter-independent/solution.md diff --git a/1-js/6-deeper/2-closure/1-counter-independent/task.md b/1-js/7-deeper/2-closure/1-counter-independent/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/1-counter-independent/task.md rename to 1-js/7-deeper/2-closure/1-counter-independent/task.md diff --git a/1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/solution.js b/1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/solution.js similarity index 100% rename from 1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/solution.js rename to 1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/solution.js diff --git a/1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/source.js b/1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/source.js similarity index 100% rename from 1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/source.js rename to 1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/source.js diff --git a/1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/test.js b/1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/test.js similarity index 100% rename from 1-js/6-deeper/2-closure/2-counter-inc-dec/_js.view/test.js rename to 1-js/7-deeper/2-closure/2-counter-inc-dec/_js.view/test.js diff --git a/1-js/6-deeper/2-closure/2-counter-inc-dec/solution.md b/1-js/7-deeper/2-closure/2-counter-inc-dec/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/2-counter-inc-dec/solution.md rename to 1-js/7-deeper/2-closure/2-counter-inc-dec/solution.md diff --git a/1-js/6-deeper/2-closure/2-counter-inc-dec/task.md b/1-js/7-deeper/2-closure/2-counter-inc-dec/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/2-counter-inc-dec/task.md rename to 1-js/7-deeper/2-closure/2-counter-inc-dec/task.md diff --git a/1-js/6-deeper/2-closure/3-function-in-if/solution.md b/1-js/7-deeper/2-closure/3-function-in-if/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/3-function-in-if/solution.md rename to 1-js/7-deeper/2-closure/3-function-in-if/solution.md diff --git a/1-js/6-deeper/2-closure/3-function-in-if/task.md b/1-js/7-deeper/2-closure/3-function-in-if/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/3-function-in-if/task.md rename to 1-js/7-deeper/2-closure/3-function-in-if/task.md diff --git a/1-js/6-deeper/2-closure/4-closure-sum/solution.md b/1-js/7-deeper/2-closure/4-closure-sum/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/4-closure-sum/solution.md rename to 1-js/7-deeper/2-closure/4-closure-sum/solution.md diff --git a/1-js/6-deeper/2-closure/4-closure-sum/task.md b/1-js/7-deeper/2-closure/4-closure-sum/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/4-closure-sum/task.md rename to 1-js/7-deeper/2-closure/4-closure-sum/task.md diff --git a/1-js/6-deeper/2-closure/5-sum-many-brackets/solution.md b/1-js/7-deeper/2-closure/5-sum-many-brackets/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/5-sum-many-brackets/solution.md rename to 1-js/7-deeper/2-closure/5-sum-many-brackets/solution.md diff --git a/1-js/6-deeper/2-closure/5-sum-many-brackets/task.md b/1-js/7-deeper/2-closure/5-sum-many-brackets/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/5-sum-many-brackets/task.md rename to 1-js/7-deeper/2-closure/5-sum-many-brackets/task.md diff --git a/1-js/6-deeper/2-closure/6-filter-through-function/_js.view/solution.js b/1-js/7-deeper/2-closure/6-filter-through-function/_js.view/solution.js similarity index 100% rename from 1-js/6-deeper/2-closure/6-filter-through-function/_js.view/solution.js rename to 1-js/7-deeper/2-closure/6-filter-through-function/_js.view/solution.js diff --git a/1-js/6-deeper/2-closure/6-filter-through-function/_js.view/source.js b/1-js/7-deeper/2-closure/6-filter-through-function/_js.view/source.js similarity index 100% rename from 1-js/6-deeper/2-closure/6-filter-through-function/_js.view/source.js rename to 1-js/7-deeper/2-closure/6-filter-through-function/_js.view/source.js diff --git a/1-js/6-deeper/2-closure/6-filter-through-function/_js.view/test.js b/1-js/7-deeper/2-closure/6-filter-through-function/_js.view/test.js similarity index 100% rename from 1-js/6-deeper/2-closure/6-filter-through-function/_js.view/test.js rename to 1-js/7-deeper/2-closure/6-filter-through-function/_js.view/test.js diff --git a/1-js/6-deeper/2-closure/6-filter-through-function/solution.md b/1-js/7-deeper/2-closure/6-filter-through-function/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/6-filter-through-function/solution.md rename to 1-js/7-deeper/2-closure/6-filter-through-function/solution.md diff --git a/1-js/6-deeper/2-closure/6-filter-through-function/task.md b/1-js/7-deeper/2-closure/6-filter-through-function/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/6-filter-through-function/task.md rename to 1-js/7-deeper/2-closure/6-filter-through-function/task.md diff --git a/1-js/6-deeper/2-closure/7-sort-by-field/solution.md b/1-js/7-deeper/2-closure/7-sort-by-field/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/7-sort-by-field/solution.md rename to 1-js/7-deeper/2-closure/7-sort-by-field/solution.md diff --git a/1-js/6-deeper/2-closure/7-sort-by-field/task.md b/1-js/7-deeper/2-closure/7-sort-by-field/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/7-sort-by-field/task.md rename to 1-js/7-deeper/2-closure/7-sort-by-field/task.md diff --git a/1-js/6-deeper/2-closure/8-make-army/_js.view/solution.js b/1-js/7-deeper/2-closure/8-make-army/_js.view/solution.js similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/_js.view/solution.js rename to 1-js/7-deeper/2-closure/8-make-army/_js.view/solution.js diff --git a/1-js/6-deeper/2-closure/8-make-army/_js.view/source.js b/1-js/7-deeper/2-closure/8-make-army/_js.view/source.js similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/_js.view/source.js rename to 1-js/7-deeper/2-closure/8-make-army/_js.view/source.js diff --git a/1-js/6-deeper/2-closure/8-make-army/_js.view/test.js b/1-js/7-deeper/2-closure/8-make-army/_js.view/test.js similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/_js.view/test.js rename to 1-js/7-deeper/2-closure/8-make-army/_js.view/test.js diff --git a/1-js/6-deeper/2-closure/8-make-army/lexenv-makearmy.png b/1-js/7-deeper/2-closure/8-make-army/lexenv-makearmy.png similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/lexenv-makearmy.png rename to 1-js/7-deeper/2-closure/8-make-army/lexenv-makearmy.png diff --git a/1-js/6-deeper/2-closure/8-make-army/lexenv-makearmy@2x.png b/1-js/7-deeper/2-closure/8-make-army/lexenv-makearmy@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/lexenv-makearmy@2x.png rename to 1-js/7-deeper/2-closure/8-make-army/lexenv-makearmy@2x.png diff --git a/1-js/6-deeper/2-closure/8-make-army/solution.md b/1-js/7-deeper/2-closure/8-make-army/solution.md similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/solution.md rename to 1-js/7-deeper/2-closure/8-make-army/solution.md diff --git a/1-js/6-deeper/2-closure/8-make-army/task.md b/1-js/7-deeper/2-closure/8-make-army/task.md similarity index 100% rename from 1-js/6-deeper/2-closure/8-make-army/task.md rename to 1-js/7-deeper/2-closure/8-make-army/task.md diff --git a/1-js/6-deeper/2-closure/article.md b/1-js/7-deeper/2-closure/article.md similarity index 100% rename from 1-js/6-deeper/2-closure/article.md rename to 1-js/7-deeper/2-closure/article.md diff --git a/1-js/6-deeper/2-closure/lexenv-if.png b/1-js/7-deeper/2-closure/lexenv-if.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-if.png rename to 1-js/7-deeper/2-closure/lexenv-if.png diff --git a/1-js/6-deeper/2-closure/lexenv-if@2x.png b/1-js/7-deeper/2-closure/lexenv-if@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-if@2x.png rename to 1-js/7-deeper/2-closure/lexenv-if@2x.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-1.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-1.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-1.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-1.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-1@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-1@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-1@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-1@2x.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-2.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-2.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-2.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-2.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-2@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-2@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-2@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-2@2x.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-3.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-3.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-3.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-3.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-3@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-3@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-3@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-3@2x.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-4.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-4.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-4.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-4.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-4@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-4@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-4@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-4@2x.png diff --git a/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5.png new file mode 100644 index 00000000..045b0516 Binary files /dev/null and b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5.png differ diff --git a/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5@2x.png new file mode 100644 index 00000000..3a5ae908 Binary files /dev/null and b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-5@2x.png differ diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-6.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-6.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-6.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-6.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-makecounter-6@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-makecounter-6@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-makecounter-6@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-makecounter-6@2x.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-work.png b/1-js/7-deeper/2-closure/lexenv-nested-work.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-work.png rename to 1-js/7-deeper/2-closure/lexenv-nested-work.png diff --git a/1-js/6-deeper/2-closure/lexenv-nested-work@2x.png b/1-js/7-deeper/2-closure/lexenv-nested-work@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexenv-nested-work@2x.png rename to 1-js/7-deeper/2-closure/lexenv-nested-work@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global-2.png b/1-js/7-deeper/2-closure/lexical-environment-global-2.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global-2.png rename to 1-js/7-deeper/2-closure/lexical-environment-global-2.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global-2@2x.png b/1-js/7-deeper/2-closure/lexical-environment-global-2@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global-2@2x.png rename to 1-js/7-deeper/2-closure/lexical-environment-global-2@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global-3.png b/1-js/7-deeper/2-closure/lexical-environment-global-3.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global-3.png rename to 1-js/7-deeper/2-closure/lexical-environment-global-3.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global-3@2x.png b/1-js/7-deeper/2-closure/lexical-environment-global-3@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global-3@2x.png rename to 1-js/7-deeper/2-closure/lexical-environment-global-3@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global.png b/1-js/7-deeper/2-closure/lexical-environment-global.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global.png rename to 1-js/7-deeper/2-closure/lexical-environment-global.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-global@2x.png b/1-js/7-deeper/2-closure/lexical-environment-global@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-global@2x.png rename to 1-js/7-deeper/2-closure/lexical-environment-global@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-simple-lookup.png b/1-js/7-deeper/2-closure/lexical-environment-simple-lookup.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-simple-lookup.png rename to 1-js/7-deeper/2-closure/lexical-environment-simple-lookup.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-simple-lookup@2x.png b/1-js/7-deeper/2-closure/lexical-environment-simple-lookup@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-simple-lookup@2x.png rename to 1-js/7-deeper/2-closure/lexical-environment-simple-lookup@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-simple.png b/1-js/7-deeper/2-closure/lexical-environment-simple.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-simple.png rename to 1-js/7-deeper/2-closure/lexical-environment-simple.png diff --git a/1-js/6-deeper/2-closure/lexical-environment-simple@2x.png b/1-js/7-deeper/2-closure/lexical-environment-simple@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-environment-simple@2x.png rename to 1-js/7-deeper/2-closure/lexical-environment-simple@2x.png diff --git a/1-js/6-deeper/2-closure/lexical-search-order.png b/1-js/7-deeper/2-closure/lexical-search-order.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-search-order.png rename to 1-js/7-deeper/2-closure/lexical-search-order.png diff --git a/1-js/6-deeper/2-closure/lexical-search-order@2x.png b/1-js/7-deeper/2-closure/lexical-search-order@2x.png similarity index 100% rename from 1-js/6-deeper/2-closure/lexical-search-order@2x.png rename to 1-js/7-deeper/2-closure/lexical-search-order@2x.png diff --git a/1-js/6-deeper/3-new-function/article.md b/1-js/7-deeper/3-new-function/article.md similarity index 100% rename from 1-js/6-deeper/3-new-function/article.md rename to 1-js/7-deeper/3-new-function/article.md diff --git a/1-js/6-deeper/index.md b/1-js/7-deeper/index.md similarity index 100% rename from 1-js/6-deeper/index.md rename to 1-js/7-deeper/index.md diff --git a/1-js/plan2.txt b/1-js/plan2.txt index 0d283d27..c308a758 100644 --- a/1-js/plan2.txt +++ b/1-js/plan2.txt @@ -3,27 +3,34 @@ getting-started editor devtools first-steps - hello-world (intro, scripts blocks rendering) - external-script (TODO: move defer/async out to browser part) + hello-world (intro, ext scripts) structure use strict variables (const, name things right) - types (objects, arrays create/access props, typeof) - type-conversions (conversions string/number/boolean, objects in general words, no toString/valueOf) + types (no objects, but typeof) + type-conversions (conversions string/number/boolean, no objects) operators - comparison (note about toprimitive) - destructuring (Q: move from here? need in objects) + comparison (no objects) uibasic logical-ops - while-for (labels, for..in, for..of) + while-for (labels, no objects) switch - function-basics (decl, shadowing, naming) - function-parameters (default params, rest, destructuring, spread, TODO, Q: move from here?) - function-create-advanced (function is object, FE as a method, user with methods, arrow basics NO THIS, new function) - object-methods (this, method syntax, call/apply) - object-tostring-valueof (also @@toStringTag) - primitives-methods (on-the-fly objects) + function-basics (decl, shadowing, naming, default params) + function-expressions-arrows (function expr, arrow, todo: move new Function out of this?) javascript-specials (TODO, remove it? migrate all function* to separate chapter?) +object-basics + object(props, for-in, refs, assign) + garbage-collection + object-methods (this, method syntax, no call/apply) + primitives-methods (on-the-fly objects) + symbol + object-toprimitive + array + iterable +more-syntax + function-arguments-rest-spread + destructuring-assignment (also func params destructuring) + advanced-loops (iterators over objects, arrays) code-quality debugging-chrome (TODO) coding-style (TODO) @@ -33,20 +40,21 @@ code-quality data-structures number (rounding, precision, isFinite, isNaN, parse*, Math.*) string (quotes, search, substring, tagged template notice) - object (loops++, copying, shorthands) - - other information would be too much - array (TODO: where is iterable?) - array-methods (TODO: tasks) - - would be too much + object + - WHAT HERE? + - can add prototypes or more + array-methods (TODO: translate tasks) date (TODO: tasks) map-set-weakmap-weakset ------- - <<< json? +<<< json? <<< descriptors (TODO: LATER, need JSON to output, better after inheritance to explain getOwnProps) <<< getter setter - +<<< NFE? +<<< function is object ?? +<<< call/apply? recursion ( running execution context = where + lexical environment = envrec + outer @@ -65,7 +73,6 @@ closures new function - bind, currying decorators constructors diff --git a/figures.bug.sketch b/figures.bug.sketch new file mode 100644 index 00000000..47f22bca Binary files /dev/null and b/figures.bug.sketch differ diff --git a/figures.new.sketch b/figures.new.sketch index 47f22bca..6b392a99 100644 Binary files a/figures.new.sketch and b/figures.new.sketch differ diff --git a/figures.sketch b/figures.sketch index 1b1ef311..d3a99a58 100644 Binary files a/figures.sketch and b/figures.sketch differ