up
|
@ -326,18 +326,18 @@ In other words, a company has departments.
|
|||
|
||||
Now let's say we want a function to get the sum of all salaries. How can we do that?
|
||||
|
||||
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.
|
||||
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? 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 1st case is the base of recursion, the trivial case, when we get an array.
|
||||
|
||||
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 2nd case when we gen an object 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:
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ For instance:
|
|||
- `Object.assign(dest, src1, ..., srcN)` -- copies properties from `src1..N` into `dest`.
|
||||
- ...and so on.
|
||||
|
||||
In this chapter we'll learn how to do the same. And, more importantly, how to feel comfortable working with such functions and arrays.
|
||||
In this chapter we'll learn how to do the same. And also, how to pass arrays to such functions as parameters.
|
||||
|
||||
## Rest parameters `...`
|
||||
|
||||
|
@ -96,9 +96,7 @@ showName("Julius", "Caesar");
|
|||
showName("Ilya");
|
||||
```
|
||||
|
||||
In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function, no matter their total number.
|
||||
|
||||
And it still works, we can use it today.
|
||||
In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function. And it still works, we can find it in the old code.
|
||||
|
||||
But the downside is that although `arguments` is both array-like and iterable, it's not an array. It does not support array methods, so we can't call `arguments.map(...)` for example.
|
||||
|
||||
|
@ -119,9 +117,10 @@ function f() {
|
|||
|
||||
f(1); // 1
|
||||
```
|
||||
````
|
||||
|
||||
As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either.
|
||||
````
|
||||
|
||||
|
||||
## Spread operator [#spread-operator]
|
||||
|
||||
|
|
|
@ -80,13 +80,13 @@
|
|||
<text id="..." font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="403" y="94">...</tspan>
|
||||
</text>
|
||||
<text id="makeArmy()" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<text id="makeArmy()-LexicalEn" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="403" y="64">makeArmy()</tspan>
|
||||
<tspan x="403" y="79">Lexical Environment</tspan>
|
||||
<tspan x="403" y="79">LexicalEnvironment</tspan>
|
||||
</text>
|
||||
<text id="for-block-Lexical-En" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<text id="for-block-LexicalEnv" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="278" y="14">for block</tspan>
|
||||
<tspan x="278" y="29">Lexical Environment</tspan>
|
||||
<tspan x="278" y="29">LexicalEnvironment</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
|
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
|
@ -70,7 +70,7 @@ The Lexical Environment object consists of two parts:
|
|||
1. *Environment Record* -- an object that stores all local variables as its properties (and some other information like the value of `this`).
|
||||
2. A reference to the *outer lexical environment*, the one associated with the outer code.
|
||||
|
||||
**So, a "variable" is just a property of the special internal object, `Environment Record`. "To get or change a variable" means "to get or change a property of that object".**
|
||||
**A "variable" is just a property of the special internal object, `Environment Record`. "To get or change a variable" means "to get or change a property of that object".**
|
||||
|
||||
For instance, in this simple code, there is only one Lexical Environment:
|
||||
|
||||
|
@ -80,7 +80,7 @@ This is a so-called global Lexical Environment, associated with the whole script
|
|||
|
||||
On the picture above, the rectangle means Environment Record (variable store) and the arrow means the outer reference. The global Lexical Environment has no outer reference, so it points to `null`.
|
||||
|
||||
Here's the bigger picture of what happens when a `let` changes:
|
||||
And that's how it changes when a variable is defined and assigned:
|
||||
|
||||

|
||||
|
||||
|
@ -119,7 +119,7 @@ Now let's go on and explore what happens when a function accesses an outer varia
|
|||
|
||||
During the call, `say()` uses the outer variable `phrase`, let's look at the details of what's going on.
|
||||
|
||||
First, when a function runs, a new function Lexical Environment is created automatically. That's a general rule for all functions. That Lexical Environment is used to store local variables and parameters of the call.
|
||||
When a function runs, a new Lexical Environment is created automatically to store local variables and parameters of the call.
|
||||
|
||||
For instance, for `say("John")`, it looks like this (the execution is at the line, labelled with an arrow):
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@
|
|||
<tspan x="675" y="67">null</tspan>
|
||||
</text>
|
||||
<polyline id="Rectangle-1-Copy" fill="#EC6B4E" points="3 39.7741935 3 27 12 33.3870968"></polyline>
|
||||
<text id="global-Lexical-Envir" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="440" y="15">global Lexical Environment</tspan>
|
||||
<text id="global-LexicalEnviro" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="440" y="15">global LexicalEnvironment</tspan>
|
||||
</text>
|
||||
<text id="Lexical-Environment" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="275" y="15">Lexical Environment</tspan>
|
||||
<text id="LexicalEnvironment-o" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="275" y="15">LexicalEnvironment</tspan>
|
||||
<tspan x="275" y="29">of makeCounter() call</tspan>
|
||||
</text>
|
||||
</g>
|
||||
|
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
@ -51,7 +51,7 @@
|
|||
<tspan x="4" y="19">count: 0</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g id="Group" transform="translate(606.000000, 48.000000)">
|
||||
<g id="Group" transform="translate(612.000000, 48.000000)">
|
||||
<path id="Line" d="M16.5,21.5 L2.5,21.5 L2.5,19.5 L16.5,19.5 L16.5,13.5 L30.5,20.5 L16.5,27.5 L16.5,21.5 Z" fill="#EE6B47" fill-rule="nonzero"></path>
|
||||
<text id="outer" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="0" y="11">outer</tspan>
|
||||
|
@ -64,7 +64,7 @@
|
|||
</text>
|
||||
</g>
|
||||
<text id="null" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="651" y="71">null</tspan>
|
||||
<tspan x="657" y="71">null</tspan>
|
||||
</text>
|
||||
<text id="[[Environment]]" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" fill="#8A704D">
|
||||
<tspan x="184" y="192">[[Environment]]</tspan>
|
||||
|
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |