Class 是 es6 的语法糖,es5 也能通过其他方式实现
基础
let ss = "sayHi"
class Fn {
construct(x) {
this.x = x
}
toString() {
}
[ss]() {
}
}
Obeject.keys(Fn.prototype)
Obeject.getOwnPropertyNames(Fn.prototype)
typeof Fn // function
Fn == Fn.prototype.construct // true
- Class 内部的方法不使用
function
- 方法之间不使用
;
,否则,会报错 - 方法名可以使用变量
- 写在
class
内部的方法,不可枚举,因此,使用Object.keys
无法获取 - 类的数据类型是
Function
, 类本身就指向构造函数 - 类中的方法,其实相当于写在原型上
- 这种形式,不存在变量提升
construct
- 必须使用
new
- 默认返回
this
实例对象,可以自定义返回对象return Object.create(null)
类的实例对象
- 使用
new
- 只有直接将属性定义在
this
, 那么这个属性才属于实例对象 - 所有类实例共享一个原型对象
- 获取圆形对象的方法
- 类
Fn.prototype
- 实例对象
fn.__proto__
(会依赖环境) - 实例对象
Object.getPrototypeOf(fn)
// 实例对象属性
var fn = new Fn(1)
fn.hasOwnproperty('x') // true
// 实例对象原型
var ff = new Fn(2)
fn.__proto__ = ff.__proto__ // true
小小知识点
Object.getPrototypeOf(obj)
- 当参数是字符串时,在
es6
中不会报错,回返回String.protptype
Class 表达式
const MyClass = class Me {
sayHello() {
console.log('Hello')
}
}
MyClass.sayHello()
MyClass.name // MyClass
-
Me
只能在类的内部使用 - 使用函数表达式可以构建直接使用的类
- 类有
name
属性
私有方法
有时,需要类有自己的私有方法,外部无法通过对象使用。有以下的解决方法
- 普通方法
_say
,下滑线。这只是规范约定,外部依旧可以获取fn._say
- 内部访问全局方法
- 使用 Symbol 值的唯一性
let foo = Symbol('foo')
class Fn {
say() {
// 只能内部使用
this[foo]('1')
}
// 私有方法
[foo](param) {}
}
私有属性
提案,
#
表示私有属性和私有方法
this指向
将对象中的方法解构出来,容易出错。
- 在
constructor
中手动将this
绑定到方法上 - 使用箭头函数
- 使用proxy
回忆
- 箭头函数this引用外层this,并且不会改变
- proxy基本语法
var pp = new Proxy(target,handler)
Class 的取值函数和存值函数
属性上可以设置
class Fn {
get prop() {
}
set prop(val) {
}
}
var descriptor = Object.getOwnPropertyDescriptor(Fn.prototype,"prop")
"get" in descriptor // true
- 取值函数和存值函数设置在属性的
Descriptor
对象上
Class 的 Generator方法
- class中的方法前,添加一个
*
就是generator方法
Class 的静态方法和静态属性
静态方法
- 语法,方法名前添加一个
static
就是静态方法 - 静态方法不能被实例继承
- 静态方法可以被子类继承
- 静态方法中
this
指向的是当前类
静态属性
- 只能通过
Fn.prop
的方式添加静态属性
new.target 属性
该属性一般是在构造函数中使用
- 有两个功能
- 使得当前类必须使用new
- 定义只能继承不能直接使用的类(有点像接口)
- 子类继承父类,创建子类实例时,
new target
指向子类 - 类不使用
new
,那么new.target
为undefined
class Parent {
constructor(name) {
if (new.target == Parent) {
this.name = name;
}else {
throw New Error('必须使用new生成实例')
}
}
}