目录
- 简介
- constructor 方法
- 类的实例对象
- 私有方法和私有属性
- class 的静态方法
- class 的静态属性和实例属性
- new.target 属性
1、简介
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class
关键字,可以定义类。
// ES5的方法
function Point (x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
// ES6的方法
class Point () {
constructor (x, y) {
this.x = x;
this.y = y;
}
toString(){
return '(' + this.x + ', ' + this.y + ')';
}
}
var p = new Point(1, 2);
构造函数的 prototype
属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的 prototype
属性上面。
2、constructor 方法
constructor
方法是类的默认方法,通过 new
命令生成对象实例时,自动调用该方法。一个类必须有 constructor
方法,如果没有显式定义,一个空的 constructor
方法会被默认添加。
class Point {
}
// 等同于
class Point {
constructor() {}
}
3、类的实例对象
生成类的实例对象的写法,与 ES5 完全一样,也是使用 new
命令。
类必须使用 new
调用,否则会报错。
4、类的私有方法和私有属性
ES6 目前还都不支持类的私有方法和私有属性。
目前,有一个提案,为 class
加了私有属性。方法是在属性名之前,使用 #
表示。
class Point {
#x = 1;
constructor (x = 0){
#x = x; // 也可以写成 thi.#x = x
}
get x (){
return #x;
}
set x (value){
#x = value;
}
}
类的属性名,可以采用表达式。
let methodName = 'getArea';
class Square {
constructor(length){
// ...
}
[methodName](){
// ...
}
}
上面代码中,Square
类的方法名 getArea
,是从表达式得到的。
5、class 的静态方法
如果在一个类的方法前面加上了 static
关键字,则表示该方法不会被实例继承,而是直接通过类来调用的。这个方法称为“静态方法”。
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
注意,如果静态方法包含 this
关键字,这个 this
指的是类,而不是实例。
class Foo {
static bar (count) {
this.count = count; // this 指向 Foo 类
}
}
父类的静态方法,可以被子类继承。静态方法也是可以从 super
对象上调用的。
5、class 的静态属性
静态属性指的是 Class
本身的属性,即 Class.propName
,而不是定义在实例对象(this
)上的属性。
ES6 明确规定,Class
内部只有静态方法,没有静态属性。
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
上面的写法为 Foo 类定义了一个静态属性 prop 。目前,只有这种写法可行。
但是目前有一个提案,提供了 class
静态属性的方法,使用 static
关键字。
class MyClass {
static myStaticProp = 42; // MyClass 的静态属性
constructor() {
console.log(MyClass.myStaticProp); // 42
}
}
当上述代码中的 static
去掉之后,即会实例的属性。
class MyClass {
myStaticProp = 42; // 实例的属性
constructor() {
}
}
// 相当于
class MyClass {
constructor() {
this.myStaticProp = 42; // 实例的属性
}
}
6、new.target 属性
new
是从构造函数生成实例对象的命令。ES6 为 new
命令引入了一个 new.target
属性,该属性一般用在构造函数之中,返回 new 命令作用于的那个构造函数。如果构造函数不是通过 new
命令调用的, new.target
会返回 undefined
,因此这个属性可以用来确定构造函数是怎么调用的。
需要注意的是,子类继承父类时,new.target
会返回子类。