That’s a first look at the syntax. The details are explained here: https://exploringjs.com/impatient-js/ch_variables-assignment...
But I should clarify that “immutable” here means “immutable binding”.
> Only single- and double-quoted strings are introduced at first
I had to start somewhere. Template literals and tagged templates are a more complex topic that benefits from strings already having been introduced.
> Arrow functions are introduced as just another syntax
Arrow functions are introduced in detail here: https://exploringjs.com/impatient-js/ch_callables.html
---
In general, I occasionally have to initially leave out some details so that the book can be read linearly. But those details are then filled in later in the book.
I sometimes find myself informally teaching devs less experienced with the language, and I've learned to cover this part of it very early. It's not made terribly obvious in a lot of resources people have mentioned using, and I've yet to encounter a case where developing that understanding failed to help someone better understand the code they were writing, and thus write better code. (Usually I'm also reviewing a lot of their PRs, and that makes the change pretty easy to see.)
I've been looking a long time for a good "Javascript in a Box" that I can give to mentees as a tool for extended learning beyond what we can cover directly. Your book and its associated materials look as if they might be just the thing, and I'm evaluating them as such.
Is there an email list or something I can use to be notified when the revisions you describe have landed? I have someone already in mind to be a "beta learner", but I'd rather wait a little for the updated version, and it would help to get some kind of push when it's available.
It's a common misconception among JavaScript programmers, especially experienced ones, that such a difference exists. It doesn't.
The usual explanation is that there are value types such as number or string, and reference types such as array or object, and these are treated differently both by the assignment operator and when passing an argument into a function: the value is copied for a value type, but a reference is copied for a reference type.
This is often illustrated with an example like this:
function a( str ) {
str = 'moo';
}
let s = 'bar';
console.log( s ); // 'bar'
a( s );
console.log( s ); // still 'bar', because a string is a value type
function b( obj ) {
obj.foo = 'moo';
}
let thing = { foo: 'bar' };
console.log( thing.foo ); // 'bar'
b( thing );
console.log( thing.foo ); // now 'moo', because an object is a reference type
This code does work as the comments describe: 'thing.foo' changes but 'n' doesn't. But this is not because of any distinction between "value types" and "reference types".It's because the code in the a() and b() functions is different!
The code in a() reassigns the function parameter (which is a local variable) to a new value. The code in b() doesn't do this, it sets a property of its parameter.
The difference in behavior is solely due to this difference in code.
Every example that purports to illustrate how "value types" and "reference types" are handled differently in assignment or parameter passing makes this same mistake.
To illustrate further, strings are commonly described as a "value type", as in the example above, and most of these discussions say that when you assign or pass a value type, the entire value is copied. But no JavaScript engine worth its salt does this. If you have code like this:
let str = 'one billion characters here';
let copy = str; // Does it *copy* the billion characters? Of course not.
Now for a short fixed-length value such as a number, a JavaScript engine may well store and copy the actual value. But this is an internal optimization, not part of the JavaScript language. It is fundamentally unknowable from JavaScript code whether the engine stores the value inside its internal Value object or stores a reference.The real difference between so-called value and reference types is that the latter may have mutable properties and the former don't.
One last illustration: if you have an object and then call Object.freeze() on it, the object now has no mutable properties (and none can be added). Does that convert this "reference" type into a "value" type where future assignments will copy the value instead of copying a reference? No. It's just been made immutable.
I will be happy to discuss further if anyone has questions or disagrees.
You're right that the description I gave is fundamentally a false one. But it is a harmless, and an extremely useful, lie.
(In any case, you're underplaying your hand here. If you're going to get deep into the weeds on how Javascript values really work, why leave out implicit autoboxing?)
- reference/value _data types_ - call by reference/value/value result/etc _evaluation strategies_ - (im)mutability
JavaScript has both reference types and (what are treated in the abstract if not in implementation as) value types. It also implements (solely) a call by value evaluation strategy, which is orthogonal to the previous statement.
Consider that this may simply be a knowledge gap on your end. I think most programmers understand the concept of value vs reference types and would not assume an object to be a value type. Obviously the reference is immutable, as is any other value type you assign to the const.
> nor the implicit return of last block statement are mentioned
Probably not mentioned because it doesn’t exist. There is no implicit return of the last block statement. That statement is misleading in at least two ways: there cannot be multiple top-level block statements as the body of a function, nor does the singular block statement body of an arrow function implicitly return the last expression. It actually requires an explicit return statement. On the other hand, an arrow function with an expression body -does- implicitly return.
My experience says this is very far from the truth. JavaScript's implementation of const is confusing for almost everyone the first time they come across it, especially the area you're talking about - changing collections. Junior engineers and non JavaScript senior engineers alike don't seem to understand what const actually means until they dig in to get deeper context, which I would point as a pretty big failure of language design.
I came late to that myself, not encountering it as a discrete concept until I got interested in Lisp, and found it clarified a great deal for me that had previously been obscure.
With that concept available, const is trivially explained as an immutable binding, as indeed the author of the book under discussion explains it elsewhere in this comment thread.
Without it, yeah, const feels full of special cases, just like everything else involving non-primitive types. It's something I've learned to cover early in teaching the language, because a little early effort there goes a long way toward clearing up a lot of confusion later.
I seem to have chosen my wording badly, since I did not mean (labeled) blocks, but indeed the expression body (which may have been referenced in the book as a ”block”, too lazy to check).
[1]https://github.com/getify/You-Dont-Know-JS [2]https://eloquentjavascript.net/
For example:
- The first variable using `const` is called ”immutable”, which is misleading, since only the _assignment_ is immutable. Later on the same page, a const object property is assigned to without any clarification as to why it works.
- Only single- and double-quoted strings are introduced at first, even though template strings are arguably the cleanest for building strings.
- Arrow functions are introduced as just another syntax - neither implicit `this` binding nor implicit return of last block statement are mentioned.