代码之家  ›  专栏  ›  技术社区  ›  seeker_of_bacon

为什么类名即使在被重新定义之后也可以在类内被引用?

  •  5
  • seeker_of_bacon  · 技术社区  · 6 年前

    如您所料,以下操作不起作用:

    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 参考号?

    3 回复  |  直到 6 年前
        1
  •  7
  •   Bergi    6 年前

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

    语法到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

        2
  •  0
  •   Ethan Herbertson    6 年前

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

        3
  •  -1
  •   Nandl66    6 年前

    在第二个示例中,您得到1,因为您引用的是静态变量,即使它在使用之前未实例化的类中也是如此。删除静态文件并正确实例化它仍然返回1:

    class User {
        foo() {
            this.prop = 1;
        }
    }
    
    let User2 = new User();
    User = null;
    
    User2.foo();
    console.log(">>" + User2.prop);  // 1
    

    注意 User = null 与此无关。

    推荐文章