diff --git a/1-js/07-object-oriented-programming/09-class/article.md b/1-js/07-object-oriented-programming/09-class/article.md index ec50d930..9c757722 100644 --- a/1-js/07-object-oriented-programming/09-class/article.md +++ b/1-js/07-object-oriented-programming/09-class/article.md @@ -43,7 +43,7 @@ let user = new User("John"); user.sayHi(); ``` -It's easy to see that the two examples are alike. So, what exactly the `class` does? We may think that it defines a new language-level entity, but that would be wrong. +It's easy to see that the two examples are alike. So, what exactly does `class` do? We may think that it defines a new language-level entity, but that would be wrong. The `class User {...}` here actually does two things: @@ -98,11 +98,11 @@ Class definition sets `enumerable` flag to `false` for all methods in the `"prot ``` ```smart header="What if there's no constructor?" -If there's no `constructor` in the `class` construct, then an empty function is generated, same as if write `constructor() {}`. +If there's no `constructor` in the `class` construct, then an empty function is generated, same as if we had written `constructor() {}`. ``` ```smart header="Classes always `use strict`" -All code inside the class construct is automatically in the strict mode. +All code inside the class construct is automatically in strict mode. ``` ### Getters/setters @@ -273,7 +273,7 @@ articles.sort(Article.compare); alert( articles[0].title ); // Body ``` -Here `Article.compare` stands "over" the articles, as a meants to compare them. +Here `Article.compare` stands "over" the articles, as a means to compare them. Another example would be a so-called "factory" method, that creates an object with specific parameters. diff --git a/1-js/07-object-oriented-programming/10-class-inheritance/article.md b/1-js/07-object-oriented-programming/10-class-inheritance/article.md index 57fef34a..a26f7bcb 100644 --- a/1-js/07-object-oriented-programming/10-class-inheritance/article.md +++ b/1-js/07-object-oriented-programming/10-class-inheritance/article.md @@ -163,7 +163,7 @@ setTimeout(function() { super.stop() }, 1000); With constructors, things are is a little bit tricky. -Till now, `Rabbit` had no its own `constructor`. +Till now, `Rabbit` did not have its own `constructor`. According to the [specification](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), if a class extends another class and has no `constructor`, then the following `constructor` is generated: @@ -271,7 +271,7 @@ Yeah, indeed, let's ask ourselves, how it could technically work? When an object Maybe we can get it `[[Prototype]]` of `this`, as `this.__proto__.method`? Unfortunately, that won't work. -Let's try to do it. Without classes, using plain objects for sheer simplicity. +Let's try to do it. Without classes, using plain objects for the sake of simplicity. Here, `rabbit.eat()` should call `animal.eat()` method of the parent object: diff --git a/1-js/07-object-oriented-programming/11-instanceof/article.md b/1-js/07-object-oriented-programming/11-instanceof/article.md index 76538500..1d725eea 100644 --- a/1-js/07-object-oriented-programming/11-instanceof/article.md +++ b/1-js/07-object-oriented-programming/11-instanceof/article.md @@ -117,7 +117,7 @@ alert( rabbit instanceof Rabbit ); // false */!* ``` -That's one of reasons to evade changing `prototype`. Just to keep safe. +That's one of reasons to avoid changing `prototype`. Just to keep safe. ## Bonus: Object toString for the type diff --git a/1-js/07-object-oriented-programming/13-mixins/article.md b/1-js/07-object-oriented-programming/13-mixins/article.md index 7cdab859..624f4426 100644 --- a/1-js/07-object-oriented-programming/13-mixins/article.md +++ b/1-js/07-object-oriented-programming/13-mixins/article.md @@ -47,7 +47,7 @@ new User("Dude").sayHi(); // Hi Dude! There's no inheritance, there's a simple method copying. So `User` may extend some other class and also include the mixin to "mix-in" the additional methods. -Mixins also can also make use of inheritance. +Mixins also can make use of inheritance. For instance, here `sayHiMixin` inherits from `sayMixin`: @@ -98,7 +98,7 @@ Now a mixin for the real life. The important feature of many objects is working with events. -That is: an object should have a method to "generate an event" when something important happens to him, and other objects should be able to "subscribe" to receive such notifications. +That is: an object should have a method to "generate an event" when something important happens to it, and other objects should be able to "subscribe" to receive such notifications. An event must have a name and, if necessary, the attached data. @@ -108,7 +108,7 @@ Or, the object `menu` can generate the event `"select"` when a menu item is sele Events is a way to "share information" with anyone who wants it. -The `eventMixin` to implement the corresponding methods: +Here is `eventMixin` that implements the corresponding methods: ```js run let eventMixin = { @@ -156,7 +156,7 @@ let eventMixin = { There are 3 methods here: -1. `.on(eventName, handler)` -- assigns the function `handler` to run when the event with that name happens. The handlers are stored in `_eventHandlers` property. +1. `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name happens. The handlers are stored in the `_eventHandlers` property. 2. `.off(eventName, handler)` -- removes the function from the handlers list. 3. `.trigger(eventName, ...args)` -- generates the event: all assigned handlers are called and `args` are passed as arguments to them. @@ -192,8 +192,8 @@ And the `eventMixin` can add such behavior to as many classes as we'd like, with *Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes. -In JavaScript that can be implemented as copying them into the prototype. +Some other languages like e.g. python allow to create mixins using multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying them into the prototype. -We can use mixins as a way to augment a class by multiple behaviors like event-handling that we overlooked above. +We can use mixins as a way to augment a class by multiple behaviors, like event-handling as we have seen above. -Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming for a mixin, to minimalize such possibility. +Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming for a mixin, to minimize such possibility. diff --git a/1-js/08-error-handling/1-try-catch/article.md b/1-js/08-error-handling/1-try-catch/article.md index 25b70d10..bc3b509b 100644 --- a/1-js/08-error-handling/1-try-catch/article.md +++ b/1-js/08-error-handling/1-try-catch/article.md @@ -110,7 +110,7 @@ try { } ``` -That's because `try..catch` actually wraps the `setTimeout` call that schedules the function. But the function itself is executed later, when the engine has already have left `try..catch` contruct. +That's because `try..catch` actually wraps the `setTimeout` call that schedules the function. But the function itself is executed later, when the engine has already have left the `try..catch` construct. To catch an exception inside a scheduled function, `try..catch` must be inside that function: ```js run @@ -222,7 +222,7 @@ try { Here we use `catch` block only to show the message, but we can do much more: a new network request, suggest an alternative to the visitor, send the information about the error to a logging facility... All much better than just dying. -## Throwing own errors +## Throwing our own errors What if `json` is syntactically correct... But doesn't have a required `"name"` property? @@ -245,7 +245,7 @@ try { Here `JSON.parse` runs normally, but the absence of `"name"` is actually an error for us. -To unify error handling, we'll use `throw` operator. +To unify error handling, we'll use the `throw` operator. ### "Throw" operator @@ -344,7 +344,7 @@ try { } ``` -Of course, everything's possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades -- suddenly a crazy bug may be discovered that leads to terrible hacks (like it happened with `ssh` tool). +Of course, everything's possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades -- suddenly a crazy bug may be discovered that leads to terrible hacks (like it happened with the `ssh` tool). In our case, `try..catch` is meant to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug. @@ -368,7 +368,7 @@ The "rethrowing" technique can be explained in more detail as: 1. Catch gets all errors. 2. In `catch(err) {...}` block we analyze the error object `err`. -2. If we don't know how to handle it, then do `throw err`. +2. If we don't know how to handle it, then we do `throw err`. In the code below, we use rethrowing so that `catch` only handles `SyntaxError`: @@ -401,7 +401,7 @@ try { } ``` -The error throwin in the line `(*)` from inside `catch` block "falls out" of `try..catch` and can be either caught by an outer `try..catch` construct (if exists), or it kills the script. +The error throwing on line `(*)` from inside `catch` block "falls out" of `try..catch` and can be either caught by an outer `try..catch` construct (if it exists), or it kills the script. So the `catch` block actually handles only errors that it knows how to deal with and "skips" all others. @@ -480,7 +480,7 @@ The code has two ways of execution: The `finally` clause is often used when we start doing something before `try..catch` and want to finalize it in any case of outcome. -For instance, we want to measure time that a Fibonacci numbers function `fib(n)` takes. Naturally, we can start measuring before it runs and finish afterwards. But what is there's an error during the function call? In particular, the implementation of `fib(n)` in the code below returns an error for negative or non-integer numbers. +For instance, we want to measure time that a Fibonacci numbers function `fib(n)` takes. Naturally, we can start measuring before it runs and finish afterwards. But what if there's an error during the function call? In particular, the implementation of `fib(n)` in the code below returns an error for negative or non-integer numbers. The `finally` clause is a great place to finish the measurements no matter what. @@ -577,7 +577,7 @@ The information from this section is not a part of the core JavaScript. Let's imagine we've got a fatal error outside of `try..catch`, and the script died. Like a programming error or something else terrible. -Is there a way to react on such a happening? We may want to log the error, show something to the user (normally he doesn't see error messages) etc. +Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally he doesn't see error messages) etc. There is none in the specification, but environments usually provide it, because it's really useful. For instance, Node.JS has [process.on('uncaughtException')](https://nodejs.org/api/process.html#process_event_uncaughtexception) for that. And in the browser we can assign a function to special [window.onerror](mdn:api/GlobalEventHandlers/onerror) property. It will run in case of an uncaught error. diff --git a/1-js/08-error-handling/2-custom-errors/article.md b/1-js/08-error-handling/2-custom-errors/article.md index 709cd359..3d1af4a8 100644 --- a/1-js/08-error-handling/2-custom-errors/article.md +++ b/1-js/08-error-handling/2-custom-errors/article.md @@ -168,7 +168,7 @@ try { The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(property)`. The human-readable `message` is generated by the constructor. -Plese note that `this.name` in `PropertyRequiredError` once again assigned manually. We could make our own "basic error" class, name it `MyError` that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in the constructor. And then inherit from it. +Please note that `this.name` in `PropertyRequiredError` once again is assigned manually. We could make our own "basic error" class, name it `MyError` that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in the constructor. And then inherit from it. Here we go: