content
content copied to clipboard
Correct description about class hoisting
Summary
Variable and class declarations are also hoisted, so they too can be referenced before they are declared. Note that doing so can lead to unexpected errors, and is not generally recommended.
This paragraph should be rephrased, or perhaps eliminated. Specifically it contradicts the class hoisting section, where it says that referencing a class before initialisation will result in an error.
Motivation
Variable and class declarations are also hoisted, so they too can be referenced before they are declared. Note that doing so can lead to unexpected errors, and is not generally recommended.
While "Variable and class declarations are also hoisted" is true, the sentence that follows, "so they too can be referenced before they are declared" is only true for variables, specifically for var declarations (differences with const and let are discussed later in the document), classes on the other hand, will fail to be referenced.
The following code will give an error:
const catClassRef = Cat;
class Cat {}
Error in NodeJS node replit
ReferenceError: Cannot access 'Cat' before initialization
at Object.<anonymous> (/home/runner/Hoisting/index.js:1:21)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
Error in Chrome codesandbox codesandbox live url
Uncaught ReferenceError: Cannot access 'Cat' before initialization
Supporting details
Metadata
- [ ] Adds a new document
- [x] Rewrites (or significantly expands) a document
- [ ] Fixes a typo, bug, or other error
@Josh-Cena
(Requesting changes just to indicate block of merge)
Hi @iamzapata I agree your change is moving this text in a "more correct" direction. However, this article, in its current form, looks dangerously misleading to me.
I spend some time reading about hoisting in various sources and briefly some time in the spec.
Before ES6, the concept was simpler since there were only var and function declarations and they were both hoisted with the intent to allow functions to be called before declaration, var hoisting was unintended consequence of function hoisting: tweet from Brendan Eich.
When we say "hoisting", we really mean that "a variable can be safely used anywhere in this scope because the interpreter has already declared it as undefined". Otherwise, if accessing a variable always throws a reference error, I personally wouldn't care if it's because I'm in the TDZ, or because it's undeclared at all.
I think we should really say "a variable can be safely ~~used~~ referenced /accessed anywhere in this scope because the interpreter has already declared it as undefined". I say this because a variable with a value of undefined in initialisation is not really useful.
Class declarations are the same as
let/constdeclarations in every way (they are all part of lexical declarations), whilefunctiondeclarations are almost the same asvardeclarations in terms of hoisting. In this case I would scope this article to talk about var and function hoisting only, with a very brief mention thatlet/const/class are not hoisted and you can't use them before declaration. What do you think?
Yes, I think there is a lot of confusion online around hoisting since class, let and const are being included in this concept, All declarations are not hoisted.
I will work on modifying this text to accommodate your suggestion.
May also be interesting to read the discussion in https://github.com/mdn/content/issues/18901. It is not fully correct to say that lexical declarations aren't hoisted either, but for the sake of pragmatism we should say they aren't.
May also be interesting to read the discussion in #18901. It is not fully correct to say that lexical declarations aren't hoisted either, but for the sake of pragmatism we should say they aren't.
Thanks, I'm going to read it.
I think it would be correct if we stick to the original intent of Hoisting, accessing before initialisation. We can think of Hoisting as the mechanism that allows functions to be invoked before declaration, with the side effect of var being initialised to undefined. Or, we can think of Hoisting as the lifting of all declarations, var, function, class, let, and const which makes things way more confusing.
Or perhaps there we are referring to hoisting in different contexts.
Hoisting, the pre ES6, when only var and function existed.
hoisting of all declarations, where it appears as every declaration is lifted in parsing, before execution
Hi @Josh-Cena , @iamzapata thanks a lot for the suggestions and comments. Is there a consensus on how to move forward on this one?
I have very little idea about how this should be approached, sorry. I will probably rewrite the entire page some time in the future.
I have very little idea about how this should be approached, sorry. I will probably rewrite the entire page some time in the future.
OK thanks. I'm going to close the pull request for the moment as we're not going to continue with it. I'll create an issue to track the problem instead and reference the changes and discussion here for context. Thanks, both!