You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Following @kentcdodds' review of Chapter 3
* Use more backticks
* Follow kent's next video
* Finished reviewing most of @kentcdodds' arguments
* defineGetter as code
Copy file name to clipboardExpand all lines: chapters/ch01.asciidoc
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,7 +37,7 @@ A couple of years later, in June 2011, the specification was once again reviewed
37
37
38
38
It took TC39 another four years to formalize ECMAScript 6, in June 2015. The sixth edition is the largest update to the language that made its way into publication, implementing many of the ES4 proposals that were deferred as part of the Harmony resolution. Throughout this book, we'll be exploring ES6 in depth.
39
39
40
-
In parallel with the ES6 effort, in 2012 the WHATWG (a standards body interested in pushing the web forward) set out to document the differences between ES5.1 and browser implementations, in terms of compatibility and interoperability requirements. The taskforce standardized +String#substr+, which was previously unspecified; unified several methods for wrapping strings in HTML tags, which were inconsistent across browsers; and documented +Object.prototype+ properties like +__proto__+ and +__defineGetter__+, among other improvementsfootnote:[For the full set of changes made when merging the Web ECMAScript specification upstream, see: https://mjavascript.com/out/javascript-standard.]. This effort was condensed into a separate Web ECMAScript specification, which eventually made its way into Annex B in 2015. Annex B was an informative section of the core ECMAScript specification, meaning implementations weren't required to follow its suggestions. Jointly with this update, Annex B was also made normative and required for web browsers.
40
+
In parallel with the ES6 effort, in 2012 the WHATWG (a standards body interested in pushing the web forward) set out to document the differences between ES5.1 and browser implementations, in terms of compatibility and interoperability requirements. The taskforce standardized +String#substr+, which was previously unspecified; unified several methods for wrapping strings in HTML tags, which were inconsistent across browsers; and documented +Object.prototype+ properties like `__proto__` and `__defineGetter__`, among other improvementsfootnote:[For the full set of changes made when merging the Web ECMAScript specification upstream, see: https://mjavascript.com/out/javascript-standard.]. This effort was condensed into a separate Web ECMAScript specification, which eventually made its way into Annex B in 2015. Annex B was an informative section of the core ECMAScript specification, meaning implementations weren't required to follow its suggestions. Jointly with this update, Annex B was also made normative and required for web browsers.
41
41
42
42
The sixth edition is a significant milestone in the history of JavaScript. Besides the dozens of new features, ES6 marks a key inflection point where ECMAScript would become a rolling standard.
Copy file name to clipboardExpand all lines: chapters/ch03.asciidoc
+16-16Lines changed: 16 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
[[classes-symbols-and-symbols]]
2
2
== Classes, Symbols, and Objects
3
3
4
-
Now that we've covered the basic improvements to the syntax, we're in good shape to take aim at a few other additions to the language: classes, and symbols. Classes provide syntax to represent prototypal inheritance under the traditional class-based programming paradigm. Symbols are a new primitive value type in JavaScript useful for defining protocols, and we'll investigate what that means. When we're done with classes and symbols, we'll discuss a few new static methods added to the +Object+ built-in in ES6.
4
+
Now that we've covered the basic improvements to the syntax, we're in good shape to take aim at a few other additions to the language: classes, and symbols. Classes provide syntax to represent prototypal inheritance under the traditional class-based programming paradigm. Symbols are a new primitive value type in JavaScript, like strings, booleans, and numbers. They can be used for defining protocols, and in this chapter we'll investigate what that means. When we're done with classes and symbols, we'll discuss a few new static methods added to the +Object+ built-in in ES6.
5
5
6
6
=== 3.1 Classes
7
7
@@ -81,7 +81,7 @@ class Fruit {
81
81
}
82
82
----
83
83
84
-
A not-so-minor detail you might have missed is that there aren't any commas in between method declarations of the +Fruit+ class. That's not a mistake our copious copy editors missed, but rather part of the +class+ syntax. The distinction can help avoid mistakes where we treat plain objects and classes as interchangeable even though they're not, and at the same time it makes classes better suited for future improvements to the syntax such as class-scoped private functions.
84
+
A not-so-minor detail you might have missed is that there aren't any commas in between method declarations of the +Fruit+ class. That's not a mistake our copious copy editors missed, but rather part of the +class+ syntax. The distinction can help avoid mistakes where we treat plain objects and classes as interchangeable even though they're not, and at the same time it makes classes better suited for future improvements to the syntax such as public and private class fields.
85
85
86
86
The class-based solution is equivalent to the prototype-based piece of code we wrote earlier. Consuming a fruit wouldn't change in the slightest, the API for +Fruit+ remains unchanged. The previous piece of code where we instantiated an apple, chopped it into smaller pieces and ate most of it would work well with our +class+ flavored +Fruit+ as well.
87
87
@@ -94,7 +94,7 @@ class Person {
94
94
}
95
95
----
96
96
97
-
Besides the class declaration syntax presented above, classes can also be declared as expressions, just like with function declarations and function expressions. You are allowed to omit the name for a +class+ expression, as shown in the following bit of code.
97
+
Besides the class declaration syntax presented above, classes can also be declared as expressions, just like with function declarations and function expressions. You may omit the name for a +class+ expression, as shown in the following bit of code.
98
98
99
99
[source,javascript]
100
100
----
@@ -105,7 +105,7 @@ const Person = class {
105
105
}
106
106
----
107
107
108
-
Class expressions could be easily returned from a function, making it possible to create a factory of classes with minimal effort. In the following example we create a +Jake+ class dynamically in arrow function which takes a name parameter and then feeds that to the parent +Person+ constructor via +super()+.
108
+
Class expressions could be easily returned from a function, making it possible to create a factory of classes with minimal effort. In the following example we create a +JakePerson+ class dynamically in arrow function which takes a name parameter and then feeds that to the parent +Person+ constructor via +super()+.
109
109
110
110
[source,javascript]
111
111
----
@@ -114,8 +114,8 @@ const createPersonClass = name => class extends Person {
114
114
super(name)
115
115
}
116
116
}
117
-
const Jake = createPersonClass('Jake')
118
-
const jake = new Jake()
117
+
const JakePerson = createPersonClass('Jake')
118
+
const jake = new JakePerson()
119
119
----
120
120
121
121
We'll dig deeper into class inheritance later. Let's take a more nuanced look at properties and methods first.
@@ -128,7 +128,7 @@ It should be noted that the +constructor+ method declaration is an optional memb
128
128
----
129
129
class Fruit {
130
130
}
131
-
// the constructor function below is equivalent to the class above
131
+
// the constructor function below is roughly equivalent to the class above
132
132
function Fruit () {
133
133
}
134
134
----
@@ -360,12 +360,12 @@ Like numbers or strings, symbols are immutable. Unlike other value types, howeve
Symbols are of type +symbol+, new in ES6. The following snippet shows how +typeof+ returns the new type string for symbols.
@@ -512,7 +512,7 @@ Besides local symbols, there's also a global symbol registry, accessible from ac
512
512
513
513
==== 3.2.3 Global Symbol Registry
514
514
515
-
A code realm is any JavaScript execution context, such as the page your application is running in, an +<iframe>+ within that page, an script running through +eval+, or a worker of any kind -- such as web workers, service workers, or shared workers. Each of these execution contexts has its own global object. Global variables defined on the +window+ object of a page, for example, aren't available to a +ServiceWorker+. In contrast, the global symbol registry is shared across all code realms.
515
+
A code realm is any JavaScript execution context, such as the page your application is running in, an +<iframe>+ within that page, a script running through +eval+, or a worker of any kind -- such as web workers, service workers, or shared workersfootnote:[Workers are a way of executing background tasks in browsers. The initiator can communicate with their workers, which run in a different execution context, via messaging. https://mjavascript.com/out/workers]. Each of these execution contexts has its own global object. Global variables defined on the +window+ object of a page, for example, aren't available to a +ServiceWorker+. In contrast, the global symbol registry is shared across all code realms.
516
516
517
517
There's two methods that interact with the runtime-wide global symbol registry: +Symbol.for+ and +Symbol.keyFor+. What do they do?
That contrasts with what we knew about symbols being unique. The global symbol registry keeps track of symbols by their +key+. Note that the +key+ will also be used as a +description+ when the symbols that go into the registry are created. Considering these symbols are global on a runtime-wide level, you might want to prefix symbol keys in the global registry with a value that identifies your library or component, mitigating potential name clashes.
532
+
The global symbol registry keeps track of symbols by their +key+. Note that the +key+ will also be used as a +description+ when the symbols that go into the registry are created. Considering these symbols are global on a runtime-wide level, you might want to prefix symbol keys in the global registry with a value that identifies your library or component, mitigating potential name clashes.
533
533
534
534
===== Using +Symbol.keyFor(symbol)+ to retrieve symbol keys
535
535
@@ -576,13 +576,13 @@ console.log(s1 === s2)
576
576
// <- true
577
577
----
578
578
579
-
There's tradeoffs in using widely available symbols. On the one hand, they make it easy for libraries to expose their own symbols, but on the other hand they could also expose their symbols on their own API, using local symbols. The symbol registry is obviously useful when symbols need to be shared across any two code realms, for example: +ServiceWorker+ and a web page. The API is also convenient when you don't want to bother storing references to the symbols, you could use the registry directly for that, since every call with a given +key+ is guaranteed to return the same +symbol+. You'll have to keep in mind, though, that these symbols are shared across the runtime and that might lead to unwanted consequences if you use generic symbol names like +each+ or +contains+.
579
+
There are tradeoffs in using widely available symbols. On the one hand, they make it easy for libraries to expose their own symbols, but on the other hand they could also expose their symbols on their own API, using local symbols. The symbol registry is obviously useful when symbols need to be shared across any two code realms, for example: +ServiceWorker+ and a web page. The API is also convenient when you don't want to bother storing references to the symbols, you could use the registry directly for that, since every call with a given +key+ is guaranteed to return the same +symbol+. You'll have to keep in mind, though, that these symbols are shared across the runtime and that might lead to unwanted consequences if you use generic symbol names like +each+ or +contains+.
580
580
581
-
There's one more kind of symbols, the built-in well-known symbols.
581
+
There's one more kind of symbols: built-in well-known symbols.
582
582
583
583
==== 3.2.4 Well-known Symbols
584
584
585
-
So far we've covered symbols you can create using the +Symbol+ function and those you can create through +Symbol.for+. The third and last kind of symbols we're going to cover is the well-known symbols. These are built into the language instead of created by the user, and they provide hooks into internal language behavior allowing you to extend or customize aspects of the language that weren't accessible prior to ES6.
585
+
So far we've covered symbols you can create using the +Symbol+ function and those you can create through +Symbol.for+. The third and last kind of symbols we're going to cover is the well-known symbols. These are built into the language instead of created by JavaScript developers, and they provide hooks into internal language behavior allowing you to extend or customize aspects of the language that weren't accessible prior to ES6.
586
586
587
587
A great example of how symbols can add extensibility to the language without breaking existing code is the +Symbol.toPrimitive+ well-known symbol. It can be assigned a function to determine how an object is casted into a primitive value. The function receives a +hint+ parameter that can be +'string'+, +'number'+, or +'default'+, indicating what type of primitive value is expected.
588
588
@@ -796,7 +796,7 @@ These differences may not seem like much, but dealing with +NaN+ has always been
796
796
797
797
==== 3.3.3 +Object.setPrototypeOf+
798
798
799
-
The +Object.setPrototypeOf+ method does exactly what its name conveys: it sets the prototype of an object to a reference to another object. It's considered the proper way of setting the prototype, as opposed to using +__proto__+ which is a legacy feature.
799
+
The +Object.setPrototypeOf+ method does exactly what its name conveys: it sets the prototype of an object to a reference to another object. It's considered the proper way of setting the prototype, as opposed to using `__proto__` which is a legacy feature.
800
800
801
801
Before ES6, we were introduced to +Object.create+ in ES5. Using that method, we could create an object based on any prototype passed into +Object.create+, as shown next.
802
802
@@ -824,7 +824,7 @@ Using +Object.setPrototypeOf+ to change the prototype of an object is an expensi
824
824
825
825
[quote, Mozilla Developer Network]
826
826
____
827
-
Changing the prototype of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in a +obj.__proto__ = ...+ statement, but may extend to any code that has access to any object whose prototype has been altered. If you care about performance you should avoid setting the prototype of an object. Instead, create a new object with the desired prototype using +Object.create()+.
827
+
Changing the prototype of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in a `obj.__proto__ = ...` statement, but may extend to any code that has access to any object whose prototype has been altered. If you care about performance you should avoid setting the prototype of an object. Instead, create a new object with the desired prototype using +Object.create()+.
0 commit comments