为什么类名称在重新定义之后可以在类中引用?

问题描述 投票:5回答:3

您期望的以下内容不起作用:

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

let User2 = User;
User = null;

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

但这有效:

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

let User2 = User;
User = null;

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

由于函数和类是对象,在这两种情况下我都为它设置了一个属性,为什么结果不同?它在哪里获得User参考?

javascript ecmascript-6 scope es6-class
3个回答
7
投票

named function expressions类似,classes包含在一个额外的作用域中,该作用域包含带有名称和值的不可变绑定。

如果我们忠实地将class语法贬低到ES5,我们会得到类似的东西

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

这个内部User声明是foo方法正在关闭的声明。覆盖外部变量并不重要。


0
投票

在类的声明中,该类的名称是永久绑定的。这只是老派构造函数类和正确的ES2015类之间的区别之一。 (可以安全地重新声明给定名称的功能的另一个重要区别,但是同名的类不能。)


-1
投票

在第二个例子中,你得到1,因为它指的是一个静态变量,即使它在使用它之前没有实例化的类中。删除静态并正确实例化它仍然返回1:

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

let User2 = new User();
User = null;

User2.foo();
console.log(">>" + User2.prop);  // 1

注意User = null是无关紧要的。

© www.soinside.com 2019 - 2024. All rights reserved.