diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md index bddd0934..87e723c6 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/1-output-numbers-100ms/task.md @@ -4,7 +4,7 @@ importance: 5 # Output every second -Write a function `printNumbers(from, to)` that outputs a number every second, starting from `from` and ending with `two`. +Write a function `printNumbers(from, to)` that outputs a number every second, starting from `from` and ending with `to`. Make two variants of the solution. diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md index 9d9e4611..1cb92015 100644 --- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md +++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md @@ -158,7 +158,7 @@ The `setTimeout` above schedules next call right at the end of the current one ` Recursive `setTimeout` is more flexible method than `setInterval`. This way the next call may be scheduled differently, depending on the results of the current one. -For instance, we need to write a service that each 5 seconds sends a request to server asking for data, but in case if the server is overloaded, it should increase the interval to 10, 20, 60 seconds... +For instance, we need to write a service that each 5 seconds sends a request to server asking for data, but in case the server is overloaded, it should increase the interval to 10, 20, 40 seconds... Here's the pseudocode: ```js @@ -226,7 +226,7 @@ And here is the picture for recursive `setTimeout`: That's because a new call is planned at the end of the previous one. ````smart header="Garbage collection" -When a function is passed in `setInterval/setTimeout`, an internal reference is created to it and saved in the scheduler. It prevents the function form being garbage collected, even if there are no other references to it. +When a function is passed in `setInterval/setTimeout`, an internal reference is created to it and saved in the scheduler. It prevents the function from being garbage collected, even if there are no other references to it. ```js // the function stays in memory until the scheduler calls it @@ -391,7 +391,7 @@ For server-side JavaScript, that limitation does not exist, and there exist othe Another benefit for in-browser scripts is that they can show a progress bar or something to the user. That's because the browser usually does all "repainting" after the script is complete. -So if we do a single huge function then even it changes something, the changes are not reflected in the document till it finishes. +So if we do a single huge function then even if it changes something, the changes are not reflected in the document till it finishes. Here's the demo: ```html run diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md index 04a9d39e..4af0d54c 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md @@ -6,7 +6,7 @@ importance: 5 Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper, passing the call to `f` at maximum once per `ms` milliseconds. Those calls that fall into the "cooldown" period, are ignored. -**The differnce from `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.** +**The difference with `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.** Let's check the real-life application to better understand that requirement and to see where it comes from. @@ -45,4 +45,4 @@ f1000(3); // (throttling, 1000ms not out yet) // ...outputs 3, intermediate value 2 was ignored ``` -P.S. Arguments and the context `this` passed to `f1000` should be passed to the original `f`. \ No newline at end of file +P.S. Arguments and the context `this` passed to `f1000` should be passed to the original `f`. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md index bec5639f..707bbf58 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md @@ -8,7 +8,7 @@ JavaScript gives exceptional flexibility when dealing with functions. They can b Let's say we have a function `slow(x)` which is CPU-heavy, but its results are stable. In other words, for the same `x` it always returns the same result. -If the function is called often, we may want to cache (remember) the results for different `x` to evade spending extra-time on recalculations. +If the function is called often, we may want to cache (remember) the results for different `x` to avoid spending extra-time on recalculations. But instead of adding that functionality into `slow()` we'll create a wrapper. As we'll see, there are many benefits of doing so. @@ -110,11 +110,11 @@ alert( worker.slow(2) ); // Whoops! Error: Cannot read property 'someMethod' of */!* ``` -The error occurs in the line `(*)` that tries to access `this.someMethod` and fails. Guess you can see, why? +The error occurs in the line `(*)` that tries to access `this.someMethod` and fails. Can you see why? -The reason is that the wrapper calls the original function as `func(x)` in the line `(**)`. And, when called like this, the function gets `this = undefined`. +The reason is that the wrapper calls the original function as `func(x)` in the line `(**)`. And, when called like that, the function gets `this = undefined`. -As if we run: +We would observe a similar symptom if we tried to run: ```js let func = worker.slow; @@ -133,7 +133,7 @@ The syntax is: func.call(context, arg1, arg2, ...) ``` -It runs the `func` providing the first argument as `this`, and the next as the arguments. +It runs `func` providing the first argument as `this`, and the next as the arguments. To put it simple, these two calls do almost the same: ```js @@ -173,7 +173,7 @@ say.call( user, "Hello" ); // John: Hello ``` -For our case, we can use `call` in the wrapper to pass the context to the original function: +In our case, we can use `call` in the wrapper to pass the context to the original function: ```js run @@ -210,7 +210,7 @@ alert( worker.slow(2) ); // works, doesn't call the original (cached) Now everything is fine. -To put all clear, let's see more deeply how `this` is passed along: +To make it all clear, let's see more deeply how `this` is passed along: 1. After the decoration `worker.slow` is now the wrapper `function (x) { ... }`. 2. So when `worker.slow(2)` is executed, the wrapper gets `2` as an argument and `this=worker` (it's the object before dot). @@ -305,11 +305,11 @@ If we look more closely, there's a minor difference between such uses of `call` - The spread operator `...` allows to pass *iterable* `args` as the list to `call`. - The `apply` accepts only *array-like* `args`. -So, these calls complement to each other. Where we expect an iterable, `call` works, where we expect an array-like, `apply` works. +So, these calls complement each other. Where we expect an iterable, `call` works, where we expect an array-like, `apply` works. And if `args` is both iterable and array-like, like a real array, then we technically could use any of them, but `apply` will probably be faster, because it's a single operation. Most JavaScript engines internally optimize is better than a pair `call + spread`. -One of most important uses of `apply` is passing the call to another function, like this: +One of the most important uses of `apply` is passing the call to another function, like this: ```js let wrapper = function() { @@ -438,7 +438,7 @@ So, technically it takes `this` and joins `this[0]`, `this[1]` ...etc together. *Decorator* is a wrapper around a function that alters its behavior. The main job is still carried out by the function. -It is generally safe to replace a function or a method with decorated one, except for one little thing. If the original function had properties on it, like `func.calledCount` or whatever, then the decorated one will not provide them. Because that is a wrapper. So one need to be careful if he uses them. Some decorators provide their own properties. +It is generally safe to replace a function or a method with a decorated one, except for one little thing. If the original function had properties on it, like `func.calledCount` or whatever, then the decorated one will not provide them. Because that is a wrapper. So one need to be careful if one uses them. Some decorators provide their own properties. Decorators can be seen as "features" or "aspects" that can be added to a function. We can add one or add many. And all this without changing its code! @@ -458,4 +458,4 @@ let wrapper = function() { We also saw an example of *method borrowing* when we take a method from an object and `call` it in the context of another object. It is quite common to take array methods and apply them to arguments. The alternative is to use rest parameters object that is a real array. -There are many decorators there in the wilds. Check how well you got them by solving the tasks of this chapter. +There are many decorators there in the wild. Check how well you got them by solving the tasks of this chapter. diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md index f293b072..97e1c280 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md @@ -10,6 +10,6 @@ f = f.bind( {name: "John"} ).bind( {name: "Pete"} ); f(); // John ``` -The exotic [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) object returned by `f.bind(...)` remembers the context (and arguments if provided) only at the creation time. +The exotic [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) object returned by `f.bind(...)` remembers the context (and arguments if provided) only at creation time. A function cannot be re-bound. diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md index a1e5195d..eb19e664 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md @@ -2,7 +2,7 @@ importance: 5 --- -# Ask loosing this +# Ask losing this The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer. diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 713e342e..87637929 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -5,15 +5,15 @@ libs: # Function binding -When using `setTimeout` with object methods or passing object methods along, there's a known problem: "loosing `this`". +When using `setTimeout` with object methods or passing object methods along, there's a known problem: "losing `this`". Suddenly, `this` just stops working right. The situation is typical for novice developers, but happens with experienced ones as well. [cut] -## Loosing "this" +## Losing "this" -We already know that in JavaScript it's easy to loose `this`. Once a method is passed somewhere separately from the object -- `this` is lost. +We already know that in JavaScript it's easy to lose `this`. Once a method is passed somewhere separately from the object -- `this` is lost. Here's how it may happen with `setTimeout`: @@ -72,7 +72,7 @@ setTimeout(() => user.sayHi(), 1000); // Hello, John! Looks fine, but a slight vulnerability appears in our code structure. -What is before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, the it will call the wrong object! +What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, the it will call the wrong object! ```js run diff --git a/1-js/06-advanced-functions/11-currying-partials/article.md b/1-js/06-advanced-functions/11-currying-partials/article.md index 78fa6899..38681c03 100644 --- a/1-js/06-advanced-functions/11-currying-partials/article.md +++ b/1-js/06-advanced-functions/11-currying-partials/article.md @@ -105,7 +105,7 @@ The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that call - Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`) - Then gives it `...args` -- arguments given to the wrapper (`"Hello"`) -So easy to do it the spread operator, right? +So easy to do it with the spread operator, right? Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library. @@ -160,7 +160,7 @@ function curry(f) { Advanced currying allows both to keep the function callable normally and to get partials easily. To understand the benefits we definitely need a worthy real-life example. -For instance, we have the logging function `log(date, importance, message)` that formats and output the information. In real projects such functions also have many other useful features like: sending it over the network or filtering: +For instance, we have the logging function `log(date, importance, message)` that formats and outputs the information. In real projects such functions also have many other useful features like: sending it over the network or filtering: ```js function log(date, importance, message) { @@ -205,7 +205,7 @@ todayDebug("message"); // [HH:mm] DEBUG message ``` So: -1. We didn't loose anything after currying: `log` is still callable normally. +1. We didn't lose anything after currying: `log` is still callable normally. 2. We were able to generate partial functions that are convenient in many cases. ## Advanced curry implementation diff --git a/1-js/06-advanced-functions/12-arrow-functions/article.md b/1-js/06-advanced-functions/12-arrow-functions/article.md index 0d8b2426..dcae22a4 100644 --- a/1-js/06-advanced-functions/12-arrow-functions/article.md +++ b/1-js/06-advanced-functions/12-arrow-functions/article.md @@ -125,4 +125,4 @@ Arrow functions: - Can't be called with `new`. - (They also don't have `super`, but we didn't study it. Will be in the chapter ). -That's because they are meant for short pieces of code that does not have the own "context", but rather works in the current one. And they really shine in that use case. +That's because they are meant for short pieces of code that does not have their own "context", but rather works in the current one. And they really shine in that use case.