在ES6中使用命名或未命名的类表达式有什么用?

时间:2016-01-02 11:27:55

标签: javascript ecmascript-6

在代码中我使用的是命名类“Car”。现在,如果我尝试使用像var carNew = new Car("ferrari");那样,那么它会给我一个错误。 那么ES6中命名类表达式的用途是什么?

'use strict';
var car = class Car{
  constructor(model){
        this.model = model;
    }
}
var carNew = new car("ferrari");

console.log(carNew); //car {model: "ferrari"}
console.log(carNew.constructor == car); //true

5 个答案:

答案 0 :(得分:9)

对于类表达式,您可以使用类名 内部,但不在类之外:

const Foo = class Self {
  static greetingPrefix() {
    return 'Hello, ';
  }

  greeting() {
    return Self.greetingPrefix() + 'World';
  }
};

const foo = new Foo();
console.log(foo.greeting()); // "Hello, World"


console.log(Self); // throws "Uncaught ReferenceError: Self is not defined"

答案 1 :(得分:7)

使用以下代码

var car = class Car{ /* ... */ }
  

var carNew = new Car("ferrari");会抛出错误,为什么?

Car尚未进入范围,因为您已编写类表达式,类似于在函数表达式中使用function

var foo = function Bar() {};
foo; // defined
Bar; // undefined
  

var carNew = new car("ferrari");有效,为什么?

出于与上述相同的推理,car标识符在您的范围内定义并指向类表达式

  

使用命名或未命名的类表达式[...]?

让我们再次回顾function。所以现在想一想,如果Bar没有在我们工作的范围内定义,它在哪里定义?

嗯,显然我们有foo.name === 'Bar',但我们也可以

var foo = function Bar() {console.log(Bar)};
foo(); // Bar logged, we see Bar === foo here

很好,所以我们可以在函数中引用Bar

class完全相同,我们可以在类表达式中引用Car,让我们执行递归行为或将静态引用复制到实例等。

我已经添加了这样的引用,以便在下面的代码中轻松查看

var car = class Car {
    constructor(model) {
        this.model = model;
        this.foo = Car; // the big C Car that was ReferenceErroring outside
    }
};
var bar = new car();
console.log(bar.foo); // logs class Car (=== car)

答案 2 :(得分:2)

与命名/未命名函数相同的用法。查看函数行为:

var a = function b() { console.log('b') }
>> undefined
a()
>> b
b()
>> Uncaught ReferenceError: b is not defined(…)

这与你的情况非常相似。

您需要使用它的地点和原因?通常,函数的唯一用例是命名一次调用的函数,它为您提供了一种自我记录功能:

(function bootstrap() {
  //
})();

此处的功能名称表示您的功能会引导您的应用。

所以我现在可以想象该类的另一个案例:你可以将它用于singleton类,它们只用于创建一个对象:

var a = new (class Car{
  constructor(model){
        this.model = model;
    }
})('ferrari');

console.log(a.model);

在这里,您只需将该类命名为知道它正在做什么,但该名称将无法在其他地方访问。

答案 3 :(得分:1)

由于未声明Car变量,因此抛出错误。

来自JavaScript | MDN文档:

  

函数声明和类之间的重要区别   声明是函数声明被提升和类   声明不是。首先需要声明你的课程   访问它,否则如下所示的代码将抛出一个   的ReferenceError

所以,使用:

var newCar = Car('ferrari');

您必须定义Car变量:

var Car = class Car{
  constructor(model){
        this.model = model;
    }
}

请注意,我们使用Car而非car

关于unamed和命名类表达式,以下是 JavaScript |的示例MDN文档

  

类表达式是另一种定义类的方法。类表达式   可以命名或未命名。命名类表达式的名称是   课堂上的当地人。

// unnamed
var Polygon = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

// named
var Polygon = class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

阅读ES6 classes - JavaScript | MDN了解更多信息

答案 4 :(得分:0)

班级表达

与函数类似,有两种类定义,两种定义类的方法:类声明和类表达式。

与函数类似,类表达式的标识符仅在表达式中可见:

const MyClass = class Me {
    getClassName() {
        return Me.name;
    }
};
const inst = new MyClass();
console.log(inst.getClassName()); // Me
console.log(Me.name); // ReferenceError: Me is not defined