说明:
1.让对象原型的写法更清晰,更像面向对象编程的一种语法糖而已;
2.构造函数的另外一种结构更清晰,更像面向对象形式的写法;
3.本质上,ES6 的类只是 ES5 的构造函数的一层包装;
- 基本语法:
// 传统JS写法:
function a(x, y) {
this.x = x;
this.y = y;
}
a.prototype.say = function () {
console.log(this.x, this.y)
}
const b = new a(1, 2);
b.say();
// ES6 class写法:
class Aclass {
// constructor为构造方法,在new实列的时候初始化自动调用此方法;
// 每一个class必须有一个constructo方法,没有显示定义,引擎会自动添加一个空的constructor方法;
constructor(x, y) {
this.x = x;
this.y = y;
}
say() {
console.log(this.x, this.y)
}
}
const b = new Aclass(1, 2);
b.say();
- get/set: 对某个值拦截存取行为;
class Aclass {
get prop() {
return 'getProp'
}
set prop(value) {
console.log(`setProp:${value}`)
}
}
const b = new Aclass();
b.prop;
b.prop = '1';
- static 静态方法:
class Aclass {
static fun() {
return 'fun';
}
static funA() {
return this.funB();
}
static funB() {
return 'static funB';
}
funB() {
return 'funB'
}
}
// 1.被标记方法不会被实例继承,而是表示class直接调用;
Aclass.fun(); // 'fun';
var b = new Aclass();
b.fun(); // 报错,因为fun没有被实例继承;
// 2.静态方法包含`this`关键字,这个`this`指的是类,而不是实例。
Aclass.funA() // 'static funB';
// 3.父类的静态方法,可以被子类继承。
class Bclass extends Aclass{}
Bclass.fun() // 'fun';
// 4.静态方法也是可以从`super`对象上调用的。
class Bclass extends Aclass {
static fun() {
return `${super.fun()} + Bclass`;
}
}
Bclass.fun() // 'fun + Bclass';
- 实例属性的两种写法;
// 写法1: 写在构造方法constructor中;
class Aclass {
constructor() {
this.count = 0;
}
}
// 写法2:类的最顶层,较推荐;
class Aclass {
count = 0;
}
- 私有属性/私有方法:只能在类内部访问;
class Aclass {
#x = 0;
get x() {
return `getX: ${this.#x}`;
}
set x(value) {
console.log(`setX: ${value}`);
this.#x = value;
}
#funA() {
return '#funA';
}
funB() {
return this.#funA();
}
}
var b = new Aclass();
// 私有属性 #x;
b.x; // 'getX: 0';
b.#x // 报错;
// 私有方法 #funA;
b.funB(); // '#funA';
b.#funA(); // 报错;
// 为何没有采用`private`关键字?
// JS是一门动态语言,没有类型声明,使用独立的符号似乎是唯一的比较方便可靠的方法,能够准确地区分一种属性是否为私有属性。
注意点:
1.类和模块内部默认就是严格模式;
2.类不存在变量提升;