Skip to content

Commit 17b8e89

Browse files
committed
get started: ch3, addressing some editorial revisions (incl moving 'prototypal classes' to apA), per getify#1552
1 parent eaf76e0 commit 17b8e89

File tree

3 files changed

+98
-59
lines changed

3 files changed

+98
-59
lines changed

get-started/apA.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,76 @@ if (Boolean(x) === true) {
254254
Since the `Boolean(..)` function always returns a value of type boolean, the `==` vs `===` in that above snippet is irrelevant; they'll both do the same thing. But the important part is to see that before the comparison, a coercion occurs, from whatever type `x` currently is, to boolean.
255255

256256
You just can't get away from coercions in JS comparisons. Buckle down and learn them.
257+
258+
## Prototypal "Classes"
259+
260+
In Chapter 3, we introduced prototypes and showed how we can link objects through a prototype chain.
261+
262+
Another way of wiring up such prototype linkages served as the (honestly, ugly) predecessor to the elegance of the ES6 `class` system (see Chapter 2), and is referred to as prototypal classes.
263+
264+
| TIP: |
265+
| :--- |
266+
| While this style of code is quite uncommon in JS these days, it's still perplexingly rather common to be asked about it in job interviews! |
267+
268+
Let's first recall the `Object.create(..)` style of coding:
269+
270+
```js
271+
var Classroom = {
272+
welcome() {
273+
console.log("Welcome, students!");
274+
}
275+
};
276+
277+
var mathClass = Object.create(Classroom);
278+
279+
mathClass.welcome();
280+
// Welcome, students!
281+
```
282+
283+
Here, a `mathClass` object is linked via its prototype to a `Classroom` object. Through this link, the `mathClass.welcome()` function call is delegated to the method defined on `Classroom`.
284+
285+
The prototypal class pattern would have labeled this delegation behavior "inheritance", and alternately have defined it (with the same behavior) as:
286+
287+
```js
288+
function Classroom() {
289+
// ..
290+
}
291+
292+
Classroom.prototype.welcome = function hello() {
293+
console.log("Welcome, students!");
294+
};
295+
296+
var mathClass = new Classroom();
297+
298+
mathClass.welcome();
299+
// Welcome, students!
300+
```
301+
302+
All functions by default reference an empty object at a property named `prototype`. Despite the confusing naming, this is **not** the function's *prototype* -- where the function is prototype linked to -- but rather the prototype object to *link to* when other objects are created by calling the function with `new`.
303+
304+
We add a `welcome` property to that empty `Classroom.prototype` object, pointing at a `hello()` function.
305+
306+
Then `new Classroom()` creates a new object (assigned to `mathClass`), and prototype links it to the existing `Classroom.prototype` object.
307+
308+
Though `mathClass` does not have a `welcome()` property/function, it successfully delegates to `Classroom.prototype.welcome()`.
309+
310+
This "prototypal class" pattern is now strongly discouraged, in favor of using ES6's `class` mechanism:
311+
312+
```js
313+
class Classroom {
314+
constructor() {
315+
// ..
316+
}
317+
318+
welcome() {
319+
console.log("Welcome, students!");
320+
}
321+
}
322+
323+
var mathClass = new Classroom();
324+
325+
mathClass.welcome();
326+
// Welcome, students!
327+
```
328+
329+
Under the covers, the same prototype linkage is wired up, but this `class` syntax fits the class-oriented design pattern much more cleanly than "prototypal classes".

get-started/ch3.md

Lines changed: 21 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@ In Chapter 2, our focus was on syntax, patterns, and behaviors. Here, our attent
1111

1212
It should be noted that this material is still not an exhaustive exposition of JS; that's what the rest of the book series is for! Here, our goal is still just to *get started*, and more comfortable with, the *feel* of JS, how it ebbs and flows.
1313

14-
This chapter should begin to answer some of the "Why?" questions that are likely cropping up as you explore JS.
14+
Be aware: this chapter digs much deeper than you're likely used to thinking about a programming language. My goal is to help you appreciate the core of how JS works, what makes it tick. This chapter will begin to answer some of the "Why?" questions that are may be cropping up as you explore JS.
15+
16+
Don't go so quickly through this material that you get lost in the weeds. As I've said a dozen times already, **take your time**. Even still, you'll probably finish this chapter with remaining questions. That's OK, though, because there's a whole book series ahead of you to explore!
1517

1618
## Closure
1719

18-
What is Closure?
20+
Perhaps without realizing it, almost every JS developer has made use of closure. In fact, closure is one of the most pervasive programming functionalities across a majority of languages. It might even be as important to understand as variables or loops, that's how fundamental it is.
1921

20-
> Closure is the ability of a function to remember and continue to access variables defined outside its scope, even when that function is executed in a different scope.
22+
Yet it feels kind of hidden, almost magical. And it's often talked about in either very abstract or very informal terms, which does little to help us nail down exactly what it is.
23+
24+
It's critical we be able to recognize where closure is used in our programs, as the presence or lack of closure is sometimes the cause of bugs (or even the source of performance impairments).
2125

22-
Perhaps without realizing it, almost every JS developer has made use of closure. It's important to be able to recognize where it's in use in your programs, as the presence or lack of closure is sometimes the cause of bugs (or even performance impairments).
26+
So can we define closure in a pragmatic way that tries to bring some concrete clarity to the topic?
27+
28+
> Closure is the ability of a function to remember and continue to access variables defined outside its scope, even when that function is executed in a different scope.
2329
24-
From the definition above, we see two parts that are critical. First, closure is a characteristic of a function. Objects don't get closures, functions do. Second, to observe a closure, you must execute a function in a different scope than where that function was originally defined.
30+
We see two definitional characteristics here. First, closure is part of the nature of a function. Objects don't get closures, functions do. Second, to observe a closure, you must execute a function in a different scope than where that function was originally defined.
2531

2632
Consider:
2733

@@ -45,7 +51,7 @@ howdy("Grant");
4551
// Howdy, Grant!
4652
```
4753

48-
First, the `greeting(..)` outer function is executed, creating an instance of the inner function `who(..)`; that function closes over the variable `msg`, the parameter from the outer scope of `greeting(..)`. We return that inner function, and assign its reference to the `hello` variable. Then we call `greeting(..)` a second time, creating a new inner function instance, with a new closure over a new `msg`, and return that reference to be assigned to `howdy`.
54+
First, the `greeting(..)` outer function is executed, creating an instance of the inner function `who(..)`; that function closes over the variable `msg`, which is the parameter from the outer scope of `greeting(..)`. When that inner function is returned, its reference is assigned to the `hello` variable in the outer scope. Then we call `greeting(..)` a second time, creating a new inner function instance, with a new closure over a new `msg`, and return that reference to be assigned to `howdy`.
4955

5056
When the `greeting(..)` function finishes running, normally we would expect all of its variables to be garbage collected (removed from memory). We'd expect each `msg` to go away, but they don't. The reason is closure. Since the inner function instances are still alive (assigned to `hello` and `howdy`, respectively), their closures are still preserving the `msg` variables.
5157

@@ -104,6 +110,8 @@ Remember: this closure is not over the value (like `1` or `3`), but over the var
104110

105111
Closure is one of the most prevalent and important programming patterns in any language. But that's especially true of JS; it's hard to imagine doing anything useful without leveraging closure in one way or another.
106112

113+
If you're still feeling unclear or shaky about closure, the majority of "Scope & Closures" (Book 2 of this series) is focused on the topic.
114+
107115
## `this` Keyword
108116

109117
One of JS's most powerful mechanisms is also one of its most misunderstood: the `this` keyword. One common misconception is that a function's `this` refers to the function itself. Because of how `this` works in other languages, another misconception is that `this` points the instance that a method belongs to. Both are incorrect.
@@ -219,7 +227,8 @@ var homework = {
219227

220228
var otherHomework = Object.create(homework);
221229

222-
otherHomework.topic; // "JS"
230+
otherHomework.topic;
231+
// "JS"
223232
```
224233

225234
`Object.create(..)` expects an argument to specify an object to link the newly created object to.
@@ -249,55 +258,9 @@ homework.topic;
249258

250259
The assignment to `topic` creates a property of that name directly on `otherHomework`; there's no affect on the `topic` property on `homework`. The next statement then accesses `otherHomework.topic`, and we see the non-delegated answer from that new property: `"Math"`.
251260

252-
### "Class" Linkage
253-
254-
Another, frankly more convoluted, way of creating an object with a prototype linkage is using the "prototypal class" pattern, from before ES6 `class` was added to the language (see Chapter 2, "Classes").
255-
256-
Consider:
257-
258-
```js
259-
function Classroom() {
260-
// ..
261-
}
262-
263-
Classroom.prototype.welcome = function hello() {
264-
console.log("Welcome, students!");
265-
};
266-
267-
var mathClass = new Classroom();
268-
269-
mathClass.welcome();
270-
// Welcome, students!
271-
```
272-
273-
All functions by default reference an empty object at a property named `prototype`. Despite the confusing naming, this is **not** the function's *prototype* -- where the function is prototype linked to -- but rather the prototype object to *link to* when other objects are created by calling the function with `new`.
274-
275-
We add a `welcome` property to that empty `Classroom.prototype` object, pointing at a `hello()` function.
276-
277-
Then `new Classroom()` creates a new object (assigned to `mathClass`), and prototype links it to the existing `Classroom.prototype` object.
278-
279-
Though `mathClass` does not have a `welcome()` property/function, it successfully delegates to `Classroom.prototype.welcome()`.
280-
281-
This "prototypal class" pattern is now strongly discouraged, in favor of ES6's `class` (see Chapter 2, "Classes"); here's the same code expressed with `class`:
282-
283-
```js
284-
class Classroom {
285-
constructor() {
286-
// ..
287-
}
288-
289-
welcome() {
290-
console.log("Welcome, students!");
291-
}
292-
}
293-
294-
var mathClass = new Classroom();
295-
296-
mathClass.welcome();
297-
// Welcome, students!
298-
```
299-
300-
Under the covers, the same prototype linkage is wired up, but this `class` syntax fits the class-oriented design pattern much more cleanly than "prototypal classes".
261+
| NOTE: |
262+
| :--- |
263+
| Another, frankly more convoluted, way of creating an object with a prototype linkage is using the "prototypal class" pattern, from before `class` (see Chapter 2, "Classes") was added in ES6. We'll cover this topic in more detail in Appendix A, "Prototypal 'Classes'". |
301264

302265
### `this` Revisited
303266

@@ -494,6 +457,6 @@ The intended take-away from this chapter is that there's a lot more to JS under
494457

495458
As you are *getting started* learning and knowing JS more closely, one of the most important skills you can practice and bolster is curiosity, and the art of asking "why?" when you encounter something in the language.
496459

497-
Even though this chapter has gone deeper on some of the topics, many details have been entirely skimmed over. There's much more to learn here, and the path to that starts with you asking the *right* questions of the code.
460+
Even though this chapter has gone quite deep on some of the topics, many details have still been entirely skimmed over. There's much more to learn here, and the path to that starts with you asking the *right* questions of your code. Asking the right questions is a critical skill of becoming a better developer.
498461

499-
In the final chapter of this book, we're going to briefly look at how to approach the rest of the *You Don't Know JS Yet* book series. Also, don't miss Appendix B of this book, which has some practice code to review some of the main topics covered in this book.
462+
In the final chapter of this book, we're going to briefly look at how JS is divided, as covered across the rest of the *You Don't Know JS Yet* book series. Also, don't skip Appendix B of this book, which has some practice code to review some of the main topics covered in this book.

get-started/toc.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
* In Order
3535
* With The Grain
3636
* Appendix A: Exploring Further
37-
* TODO
37+
* Values vs References
38+
* So Many Function Forms
39+
* Coercive Conditional Comparison
40+
* Prototypal "Classes"
3841
* Appendix B: Practice, Practice, Practice!
3942
* Practicing Comparisons
4043
* Practicing Closure

0 commit comments

Comments
 (0)