class
class 为对象提供了 状态(成员变量)的初始值 和 行为(成员函数或方法)。
class = 对象的 可扩展程序代码模版 = 状态(属性,初始值) + 行为(方法,也就是函数)
class 不需要逗号,
js
class MyClass {
// 需要 polyfill
prop = value; // 属性
static staticProp = value;
constructor(...) { // 构造器
// ...
}
method(...) {} // method
get something(...) {} // getter 方法
set something(...) {} // setter 方法
[Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)
static staticMethod() { }
}本质
js
// 这里是方便理解的伪代码
function MyClass() {}
MyClass.prototype = {
constructor: MyClass,
method() {},
get something() {},
set something() {},
[Symbol.iterator]() {}
};
MyClass.staticProp = '';
MyClass.staticMethod(){}通过 class 创建的函数具有一些特性
- use strict
- enumerable false
[[IsClassConstructor]]true
tips:Object.getOwnPropertyDescriptors( MyClass.prototype )
静态 属性 和 方法 是可被继承的
字段
字段 需要 需要 polyfill
字段 是挂在 实例上的
字段 可以用于 bind this
js
class {
method = () => {}
}继承
原型链。
extends 后可以指定任意表达式。
继承类的 constructor 必须调用 super,否则将会报错!
super
js
let animal = {
eat() {
alert(`eats.`);
},
};
let rabbit = {
__proto__: animal,
eat() {
this.__proto__.eat.call(this); // (*)
},
};
let longEar = {
__proto__: rabbit,
eat() {
this.__proto__.eat.call(this); // (**)
},
};
longEar.eat(); // Error: Maximum call stack size exceededthis 是不知道 继承关系的,所以会一直死循环。
[[HomeObject]],指向自身,处理 super
函数 不是 方法
函数是没有 [[HomeObject]]
js
let animal = {
eat: function() { }
eat() { }
};虽然二者看似一样,但是实际上差很多!
错误的 [[HomeObject]] 会导致很多内部问题!
[[HomeObject]]应该是对象方法都有的
表达式
类 的本质 就是 函数,所以 class 也支持表达式,也是一等公民
封装
内部接口与外部接口的划分被称为 封装。
用户 并不关心“内部”实现,并且将“内部”暴露给 “用户” 也不是一个明智的选择。
私有
_#
_ 是约定俗成,并不受语言保护。
# 需要 polyfills。# 支持属性 和 方法。
# 是私有的,所以 Object.getOwnPropertyDescriptors 并不能获取到相关信息。它只能内部使用。