Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why class name can be referenced inside class even after it was redefined?

The following as you'd expect doesn't work:

let User = {
    foo() {
        User.prop = 1;
    }
};

let User2 = User;
User = null;

User2.foo();  // Cannot set property of null
console.log(User2.prop);

This works, though:

class User {
    static foo() {
        User.prop = 1;
    }
}

let User2 = User;
User = null;

User2.foo();
console.log(User2.prop);  // 1

Since functions and classes are objects, and in both cases I set a property for it, why is it that the results differ? Where is it getting User reference?

like image 896
seeker_of_bacon Avatar asked Sep 13 '18 15:09

seeker_of_bacon


1 Answers

Similar to named function expressions, classes are wrapped in an extra scope that contains an immutable binding with their name and value.

If we desugar the class syntax to ES5 faithfully, we'd get something like

let User = (() => {
    const User = function() {};
//  ^^^^^^^^^^
    User.foo = function() {
        User.prop = 1;
    };
    return User;
})();

let User2 = User;
User = null;

User2.foo();
console.log(User2.prop);  // 1

This inner User declaration is the one that the foo method is closing over. Overwriting the outer variable doesn't matter to it.

like image 158
Bergi Avatar answered Oct 07 '22 02:10

Bergi